-- Cached parsed-torrent metadata. Mirrors the Rust `ParsedTorrent` struct -- field-for-field. A UUID `id` is the PK so rows can be inserted during the -- fast path (title-only, no info_hash yet) and updated when the background -- resolver finishes. -- -- A row exists in one of three states: -- 'partial' - title-derived fields only, awaiting background resolution -- 'resolving'- a background resolver task is currently fetching torrent bytes -- 'resolved' - full torrent-derived data filled in CREATE TABLE parsed_torrents ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), info_hash TEXT NOT NULL DEFAULT '', raw_title TEXT NOT NULL DEFAULT '', artist TEXT NOT NULL DEFAULT '', album TEXT NOT NULL DEFAULT '', year INTEGER NOT NULL DEFAULT 0, release_type TEXT NOT NULL DEFAULT 'unknown', genres JSONB NOT NULL DEFAULT '[]'::jsonb, label TEXT NOT NULL DEFAULT '', source TEXT NOT NULL DEFAULT 'unknown', rip_type TEXT NOT NULL DEFAULT '', format TEXT NOT NULL DEFAULT 'unknown', bitrate TEXT NOT NULL DEFAULT '', bit_depth INTEGER NOT NULL DEFAULT 0, sample_rate INTEGER NOT NULL DEFAULT 0, track_names JSONB NOT NULL DEFAULT '[]'::jsonb, track_count INTEGER NOT NULL DEFAULT 0, release_count INTEGER NOT NULL DEFAULT 0, audio_file_count INTEGER NOT NULL DEFAULT 0, total_audio_size BIGINT NOT NULL DEFAULT 0, has_cover_art BOOLEAN NOT NULL DEFAULT false, has_cue_sheet BOOLEAN NOT NULL DEFAULT false, has_rip_log BOOLEAN NOT NULL DEFAULT false, parsed_successfully BOOLEAN NOT NULL DEFAULT false, parse_errors JSONB NOT NULL DEFAULT '[]'::jsonb, -- cache-control columns (not part of ParsedTorrent) state TEXT NOT NULL DEFAULT 'partial', indexer TEXT NOT NULL DEFAULT '', magnet TEXT NOT NULL DEFAULT '', created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- enum-backed fields (release_type, source, format) are stored as their -- `as_str()` repr in plain TEXT rather than native ENUMs, so adding a variant -- to the Rust enum needs no migration. -- lets the background resolver find rows still awaiting torrent resolution CREATE INDEX parsed_torrents_state_idx ON parsed_torrents (state) WHERE state IN ('partial', 'resolving'); -- dedup resolved torrents by info_hash (only meaningful once non-empty) CREATE UNIQUE INDEX parsed_torrents_info_hash_uidx ON parsed_torrents (info_hash) WHERE info_hash != '';