-- M7 #352 slice 2: system-generated playlists. -- Adds kind/system_variant/seed_artist_id columns to playlists and a -- per-user run-tracking table. Backfills existing slice-1 playlists -- to kind='user'. -- Discriminator on existing playlists table. ALTER TABLE playlists ADD COLUMN kind text NOT NULL DEFAULT 'user', ADD COLUMN system_variant text, ADD COLUMN seed_artist_id uuid REFERENCES artists(id) ON DELETE SET NULL; -- Belt-and-braces backfill in case the DEFAULT didn't apply on some -- runtime branches; a no-op when the column metadata already filled. UPDATE playlists SET kind = 'user' WHERE kind IS NULL OR kind = ''; -- Constraint: kind/system_variant pair is consistent. ALTER TABLE playlists ADD CONSTRAINT playlists_kind_variant_consistent CHECK ( (kind = 'user' AND system_variant IS NULL) OR (kind = 'system' AND system_variant IN ('for_you', 'songs_like_artist')) ); -- Constraint: 'songs_like_artist' has a seed artist; nothing else does. ALTER TABLE playlists ADD CONSTRAINT playlists_seed_consistent CHECK ( (system_variant IS NULL AND seed_artist_id IS NULL) OR (system_variant = 'for_you' AND seed_artist_id IS NULL) OR (system_variant = 'songs_like_artist' AND seed_artist_id IS NOT NULL) ); -- Filter index for kind=user vs kind=system queries on the user's row. CREATE INDEX playlists_user_kind_idx ON playlists (user_id, kind); -- Per-user run tracking — one row per user. CREATE TABLE system_playlist_runs ( user_id uuid PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE, last_run_at timestamptz, last_run_date date, in_flight boolean NOT NULL DEFAULT false, last_error text );