-- M5c: persist unmatched-similar-artist MBIDs that the M4b worker would -- otherwise discard. Mirrors artist_similarity shape: same composite PK -- with source, same (seed_id, score DESC) index, same source enum check. -- The candidate side is text + name (no FK) — that's the whole point. CREATE TABLE artist_similarity_unmatched ( seed_artist_id uuid NOT NULL REFERENCES artists(id) ON DELETE CASCADE, candidate_mbid text NOT NULL, candidate_name text NOT NULL, score DOUBLE PRECISION NOT NULL, source text NOT NULL CHECK (source IN ('listenbrainz', 'musicbrainz_tag', 'user_cooccurrence')), fetched_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY (seed_artist_id, candidate_mbid, source) ); CREATE INDEX artist_similarity_unmatched_seed_score_idx ON artist_similarity_unmatched (seed_artist_id, score DESC);