release / govulncheck (push) Successful in 17s
release / web (push) Successful in 1m33s
release / go (push) Successful in 1m49s
release / integration (push) Successful in 5m42s
release / android (push) Successful in 5m59s
release / Build signed APK (releases and dev) (push) Successful in 6m9s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 16s
release / Verify release artifacts (tag releases only) (push) Skipped
Applies rule 32's migration exception: each header still says what the schema was, what changes and what it prevents, but task, milestone, decision and rule ids are replaced by the practice they stood for, the operator quotes by the decision, single-install counts are dropped, and pointers to a deleted package and an external design doc are gone. golang-migrate keeps no checksum, so editing applied migrations' comments is safe. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
47 lines
1.7 KiB
SQL
47 lines
1.7 KiB
SQL
-- System-generated playlists.
|
|
-- Adds kind/system_variant/seed_artist_id columns to playlists and a
|
|
-- per-user run-tracking table. Backfills existing 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
|
|
);
|