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 nodes ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, host TEXT NOT NULL, port INTEGER NOT NULL DEFAULT 22, username TEXT NOT NULL, private_key TEXT NOT NULL, ffmpeg_path TEXT NOT NULL DEFAULT 'ffmpeg', work_dir TEXT NOT NULL DEFAULT '/tmp', status TEXT NOT NULL DEFAULT 'unknown', last_checked_at TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')) ); 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, 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, original_language TEXT, orig_lang_source TEXT, needs_review INTEGER NOT NULL DEFAULT 1, imdb_id TEXT, tmdb_id TEXT, tvdb_id TEXT, scan_status TEXT NOT NULL DEFAULT 'pending', scan_error TEXT, last_scanned_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, 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, 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, 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, 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, node_id INTEGER REFERENCES nodes(id) ON DELETE SET NULL, 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 ); `; 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']), scan_running: '0', movies_path: '', series_path: '', };