-- 0035_taste_profile.up.sql — per-user taste profile (#796 phase 1). -- -- A persistent, decaying model of each user's taste, rebuilt daily from -- graded play engagement (completion + skip position) plus explicit -- likes. Two facet tables: weighted artists and weighted genre tags. -- Weight is a signed float — positive = drawn to, negative = (passively) -- avoided; magnitude reflects decayed engagement. Phase 1 only BUILDS -- these; consumption (candidate sourcing + scoring) lands in phase 2. -- -- CASCADE on user/artist deletes keeps them clean. Indexed by -- (user_id, weight DESC) to serve "top taste artists/tags" reads cheaply. CREATE TABLE taste_profile_artists ( user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, artist_id uuid NOT NULL REFERENCES artists(id) ON DELETE CASCADE, weight double precision NOT NULL, updated_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY (user_id, artist_id) ); CREATE INDEX taste_profile_artists_user_weight_idx ON taste_profile_artists (user_id, weight DESC); CREATE TABLE taste_profile_tags ( user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, tag text NOT NULL, weight double precision NOT NULL, updated_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY (user_id, tag) ); CREATE INDEX taste_profile_tags_user_weight_idx ON taste_profile_tags (user_id, weight DESC);