export const SCHEMA = ` PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON; CREATE TABLE IF NOT EXISTS config ( key TEXT PRIMARY KEY NOT NULL, value TEXT ); CREATE TABLE IF NOT EXISTS media_items ( id INTEGER PRIMARY KEY AUTOINCREMENT, jellyfin_id TEXT NOT NULL UNIQUE, type TEXT NOT NULL, name TEXT NOT NULL, original_title TEXT, series_name TEXT, series_jellyfin_id TEXT, season_number INTEGER, episode_number INTEGER, year INTEGER, file_path TEXT NOT NULL, file_size INTEGER, container TEXT, runtime_ticks INTEGER, date_last_refreshed TEXT, original_language TEXT, orig_lang_source TEXT, needs_review INTEGER NOT NULL DEFAULT 1, imdb_id TEXT, tmdb_id TEXT, tvdb_id TEXT, jellyfin_raw TEXT, external_raw TEXT, scan_status TEXT NOT NULL DEFAULT 'pending', scan_error TEXT, last_scanned_at TEXT, last_executed_at TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE IF NOT EXISTS media_streams ( id INTEGER PRIMARY KEY AUTOINCREMENT, item_id INTEGER NOT NULL REFERENCES media_items(id) ON DELETE CASCADE, stream_index INTEGER NOT NULL, type TEXT NOT NULL, codec TEXT, profile TEXT, language TEXT, language_display TEXT, title TEXT, is_default INTEGER NOT NULL DEFAULT 0, is_forced INTEGER NOT NULL DEFAULT 0, is_hearing_impaired INTEGER NOT NULL DEFAULT 0, channels INTEGER, channel_layout TEXT, bit_rate INTEGER, sample_rate INTEGER, bit_depth INTEGER, UNIQUE(item_id, stream_index) ); CREATE TABLE IF NOT EXISTS review_plans ( id INTEGER PRIMARY KEY AUTOINCREMENT, item_id INTEGER NOT NULL UNIQUE REFERENCES media_items(id) ON DELETE CASCADE, status TEXT NOT NULL DEFAULT 'pending', is_noop INTEGER NOT NULL DEFAULT 0, confidence TEXT NOT NULL DEFAULT 'low', apple_compat TEXT, job_type TEXT NOT NULL DEFAULT 'copy', subs_extracted INTEGER NOT NULL DEFAULT 0, notes TEXT, reviewed_at TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE IF NOT EXISTS stream_decisions ( id INTEGER PRIMARY KEY AUTOINCREMENT, plan_id INTEGER NOT NULL REFERENCES review_plans(id) ON DELETE CASCADE, stream_id INTEGER NOT NULL REFERENCES media_streams(id) ON DELETE CASCADE, action TEXT NOT NULL, target_index INTEGER, custom_title TEXT, transcode_codec TEXT, UNIQUE(plan_id, stream_id) ); CREATE TABLE IF NOT EXISTS subtitle_files ( id INTEGER PRIMARY KEY AUTOINCREMENT, item_id INTEGER NOT NULL REFERENCES media_items(id) ON DELETE CASCADE, file_path TEXT NOT NULL UNIQUE, language TEXT, codec TEXT, is_forced INTEGER NOT NULL DEFAULT 0, is_hearing_impaired INTEGER NOT NULL DEFAULT 0, file_size INTEGER, created_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE IF NOT EXISTS jobs ( id INTEGER PRIMARY KEY AUTOINCREMENT, item_id INTEGER NOT NULL REFERENCES media_items(id) ON DELETE CASCADE, command TEXT NOT NULL, job_type TEXT NOT NULL DEFAULT 'copy', status TEXT NOT NULL DEFAULT 'pending', output TEXT, exit_code INTEGER, created_at TEXT NOT NULL DEFAULT (datetime('now')), started_at TEXT, completed_at TEXT ); CREATE INDEX IF NOT EXISTS idx_review_plans_status ON review_plans(status); CREATE INDEX IF NOT EXISTS idx_review_plans_is_noop ON review_plans(is_noop); CREATE INDEX IF NOT EXISTS idx_stream_decisions_plan_id ON stream_decisions(plan_id); CREATE INDEX IF NOT EXISTS idx_media_items_series_jf ON media_items(series_jellyfin_id); CREATE INDEX IF NOT EXISTS idx_media_items_series_name ON media_items(series_name); CREATE INDEX IF NOT EXISTS idx_media_items_type ON media_items(type); CREATE INDEX IF NOT EXISTS idx_media_streams_item_id ON media_streams(item_id); CREATE INDEX IF NOT EXISTS idx_media_streams_type ON media_streams(type); CREATE INDEX IF NOT EXISTS idx_subtitle_files_item_id ON subtitle_files(item_id); CREATE INDEX IF NOT EXISTS idx_jobs_status ON jobs(status); CREATE INDEX IF NOT EXISTS idx_jobs_item_id ON jobs(item_id); `; export const DEFAULT_CONFIG: Record = { setup_complete: "0", jellyfin_url: "", jellyfin_api_key: "", jellyfin_user_id: "", radarr_url: "", radarr_api_key: "", radarr_enabled: "0", sonarr_url: "", sonarr_api_key: "", sonarr_enabled: "0", subtitle_languages: JSON.stringify(["eng", "deu", "spa"]), audio_languages: "[]", scan_running: "0", job_sleep_seconds: "0", scan_schedule_enabled: "0", scan_schedule_start: "01:00", scan_schedule_end: "07:00", process_schedule_enabled: "0", process_schedule_start: "01:00", process_schedule_end: "07:00", };