feat(playlists): #415 stage 1 — rotation-state schema + play ingest
First of three stages for system-playlist sample-history dedup (Fable #415, server-side rotation per the operator's choice). Schema (migration 0027): - play_events.source (nullable text): which surface a play came from. 'for_you' / 'discover' feed rotation; NULL for library / user-playlist / radio / Subsonic. - system_playlist_rotation_state(user_id, playlist_kind, played_track_ids uuid[], rotation_started_at, updated_at): the per-(user,kind) set of already-heard tracks this rotation. Ingest: - New RecordPlayStartedWithSource on the writer; RecordPlayStarted is now a thin source="" wrapper so the frozen Subsonic shim is untouched (no signature ripple). - When source is a known system kind, the same txn appends the track to rotation state (AppendRotationPlayed keeps the array a set via the conflict CASE). - /api/events play_started accepts an optional "source". No serve-behavior change yet — Stage 2 makes shuffle prefer the unplayed tail + resets on exhaustion; Stage 3 wires the clients to send source and consume the rotation-aware order. Tests: rotation appends + dedupes for a system source; source-less play writes no rotation row. (Existing RecordPlayStarted tests are unchanged — same wrapper signature, identical behavior at source="".) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -369,6 +369,7 @@ type PlayEvent struct {
|
||||
ClientID *string
|
||||
SessionVectorAtPlay []byte
|
||||
ScrobbledAt pgtype.Timestamptz
|
||||
Source *string
|
||||
}
|
||||
|
||||
type PlaySession struct {
|
||||
@@ -475,6 +476,14 @@ type SmtpConfig struct {
|
||||
UpdatedAt pgtype.Timestamptz
|
||||
}
|
||||
|
||||
type SystemPlaylistRotationState struct {
|
||||
UserID pgtype.UUID
|
||||
PlaylistKind string
|
||||
PlayedTrackIds []pgtype.UUID
|
||||
RotationStartedAt pgtype.Timestamptz
|
||||
UpdatedAt pgtype.Timestamptz
|
||||
}
|
||||
|
||||
type SystemPlaylistRun struct {
|
||||
UserID pgtype.UUID
|
||||
LastRunAt pgtype.Timestamptz
|
||||
|
||||
Reference in New Issue
Block a user