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>
27 lines
1.3 KiB
SQL
27 lines
1.3 KiB
SQL
-- 0027_system_playlist_rotation.up.sql — sample-history dedup for
|
|
-- system playlists. Two parts:
|
|
--
|
|
-- 1. play_events.source: which system playlist a play originated
|
|
-- from ('for_you' | 'discover' | future kinds), or NULL for any
|
|
-- play not launched from a system-playlist surface (library,
|
|
-- user playlist, radio, Subsonic). Lets the ingest path know a
|
|
-- play should count against that playlist's rotation.
|
|
--
|
|
-- 2. system_playlist_rotation_state: per (user, playlist_kind) set
|
|
-- of track ids already played in the current rotation window.
|
|
-- Shuffle-on-play prefers the unplayed tail; when the snapshot
|
|
-- is exhausted the set resets and rotation_started_at advances.
|
|
-- Centralized server-side so phone / web / watch share one
|
|
-- rotation, mirroring how radio dedup already lives server-side.
|
|
ALTER TABLE play_events
|
|
ADD COLUMN source text;
|
|
|
|
CREATE TABLE system_playlist_rotation_state (
|
|
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
playlist_kind text NOT NULL,
|
|
played_track_ids uuid[] NOT NULL DEFAULT '{}',
|
|
rotation_started_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (user_id, playlist_kind)
|
|
);
|