Publish current app and server
This commit is contained in:
@@ -13,6 +13,7 @@ CREATE TABLE IF NOT EXISTS sessions (
|
||||
device_name TEXT NOT NULL DEFAULT 'Memby TV',
|
||||
client_version TEXT NOT NULL DEFAULT '',
|
||||
client_protocol TEXT NOT NULL DEFAULT '',
|
||||
client_capabilities TEXT[] NOT NULL DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
last_seen_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
@@ -20,6 +21,7 @@ CREATE TABLE IF NOT EXISTS sessions (
|
||||
ALTER TABLE sessions ADD COLUMN IF NOT EXISTS device_name TEXT NOT NULL DEFAULT 'Memby TV';
|
||||
ALTER TABLE sessions ADD COLUMN IF NOT EXISTS client_version TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE sessions ADD COLUMN IF NOT EXISTS client_protocol TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE sessions ADD COLUMN IF NOT EXISTS client_capabilities TEXT[] NOT NULL DEFAULT '{}';
|
||||
|
||||
-- Older builds could create more than one token for the same physical TV. Keep the most
|
||||
-- recently used row before adding the identity constraint.
|
||||
@@ -119,6 +121,50 @@ CREATE TABLE IF NOT EXISTS search_history (
|
||||
CREATE INDEX IF NOT EXISTS search_history_user_time_idx
|
||||
ON search_history (emby_user_id, occurred_at DESC);
|
||||
|
||||
-- A user's explicitly followed TV series. Unlike library_items this is intentionally
|
||||
-- user-scoped: following a show is a Memby preference, not Emby library state.
|
||||
CREATE TABLE IF NOT EXISTS user_shows (
|
||||
emby_user_id TEXT NOT NULL,
|
||||
item_id TEXT NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
year INT,
|
||||
image_tag TEXT NOT NULL DEFAULT '',
|
||||
added_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (emby_user_id, item_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS user_shows_user_added_idx
|
||||
ON user_shows (emby_user_id, added_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_notification_preferences (
|
||||
emby_user_id TEXT PRIMARY KEY,
|
||||
enabled BOOLEAN NOT NULL DEFAULT true,
|
||||
show_return_alerts BOOLEAN NOT NULL DEFAULT true,
|
||||
lead_days INT NOT NULL DEFAULT 7 CHECK (lead_days BETWEEN 1 AND 30),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- Notifications are materialised so read/dismissed state follows the user to every TV.
|
||||
-- source_key is deterministic, preventing the same return date from being announced
|
||||
-- again whenever the app refreshes.
|
||||
CREATE TABLE IF NOT EXISTS user_notifications (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
emby_user_id TEXT NOT NULL,
|
||||
source_key TEXT NOT NULL,
|
||||
kind TEXT NOT NULL,
|
||||
item_id TEXT NOT NULL DEFAULT '',
|
||||
title TEXT NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
event_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
read_at TIMESTAMPTZ,
|
||||
dismissed_at TIMESTAMPTZ,
|
||||
UNIQUE (emby_user_id, source_key)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS user_notifications_user_created_idx
|
||||
ON user_notifications (emby_user_id, created_at DESC);
|
||||
|
||||
-- Recommendation-relevant Tracearr history. The public Tracearr API has no user or
|
||||
-- since cursor, so stable source ids make these rows the durable deduplication boundary.
|
||||
-- Deliberately omit artwork, stream-detail blobs and other fields unused by ranking.
|
||||
@@ -180,7 +226,10 @@ CREATE TABLE IF NOT EXISTS recommendation_user_profiles (
|
||||
genre_affinity JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
title_affinity JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
studio_affinity JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
context_affinity JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
codec_outcomes JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
weighted_profile JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
algorithm_version TEXT NOT NULL DEFAULT '',
|
||||
signals_through TIMESTAMPTZ,
|
||||
built_at TIMESTAMPTZ,
|
||||
pool_built_at TIMESTAMPTZ,
|
||||
@@ -188,6 +237,32 @@ CREATE TABLE IF NOT EXISTS recommendation_user_profiles (
|
||||
last_error TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
|
||||
ALTER TABLE recommendation_user_profiles
|
||||
ADD COLUMN IF NOT EXISTS context_affinity JSONB NOT NULL DEFAULT '{}'::jsonb;
|
||||
ALTER TABLE recommendation_user_profiles
|
||||
ADD COLUMN IF NOT EXISTS algorithm_version TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE recommendation_user_profiles
|
||||
ADD COLUMN IF NOT EXISTS weighted_profile JSONB NOT NULL DEFAULT '{}'::jsonb;
|
||||
|
||||
-- Explicit recommendation feedback is separate from Emby favourites: More Like This
|
||||
-- changes discovery affinity, while Not for Me is a hard user-scoped exclusion.
|
||||
CREATE TABLE IF NOT EXISTS recommendation_actions (
|
||||
emby_user_id TEXT NOT NULL,
|
||||
item_id TEXT NOT NULL,
|
||||
action TEXT NOT NULL CHECK (action IN ('more_like_this', 'not_for_me')),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (emby_user_id, item_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS recommendation_actions_user_idx
|
||||
ON recommendation_actions (emby_user_id, updated_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS recommendation_onboarding (
|
||||
emby_user_id TEXT PRIMARY KEY,
|
||||
preferences JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS recommendation_profiles_dirty_idx
|
||||
ON recommendation_user_profiles (dirty_since)
|
||||
WHERE dirty_since IS NOT NULL;
|
||||
|
||||
Reference in New Issue
Block a user