-- 0049_suggestion_snoozes.up.sql — time-boxed "not right now" on a Discover
-- artist suggestion (#2374, milestone #268 slice 3).
--
-- This is NOT a dislike. Rule #101 forbids a "Not for me" / thumbs-down /
-- exclusion UI, and a snooze deliberately isn't one: it records no verdict on
-- the music, expires on its own, and MUST NEVER feed the taste profile. It is
-- acquisition triage — "I don't want to request this right now" — so the same
-- candidate is free to return once snoozed_until passes. Anything that reads
-- this table as negative preference signal is a bug.
--
-- Per-user (rule #47), never global: one household member parking a
-- suggestion must not remove it from anyone else's deck.
--
-- candidate_mbid is text with NO foreign key, on purpose. Suggestions come
-- from artist_similarity_unmatched and are out-of-library BY DEFINITION, so
-- there is no artists row to reference — the MBID is the only stable identity
-- available. candidate_name is denormalized for the same reason: the manage /
-- un-snooze list has nowhere else to resolve a display name from.

CREATE TABLE suggestion_snoozes (
    user_id        uuid        NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    candidate_mbid text        NOT NULL,
    candidate_name text        NOT NULL,
    snoozed_until  timestamptz NOT NULL,
    created_at     timestamptz NOT NULL DEFAULT now(),
    PRIMARY KEY (user_id, candidate_mbid)
);

-- Supports the gc sweep's unqualified `WHERE snoozed_until < now()` scan. The
-- composite PK already covers every per-user read, so this is the only extra
-- index worth its write cost at household-scale row counts (same reasoning as
-- lidarr_quarantine in 0011).
CREATE INDEX suggestion_snoozes_expiry_idx ON suggestion_snoozes (snoozed_until);
