-- Rotation state for system-playlist sample-history dedup (#415). -- One row per (user, playlist_kind). played_track_ids accumulates -- tracks heard from that playlist in the current rotation; shuffle -- prefers ids NOT in this set, then resets when the snapshot is -- exhausted. -- name: AppendRotationPlayed :exec -- Records that the given track was played from the (user, kind) -- system playlist. Creates the row on first play; on conflict -- appends only if not already present so the array stays a set. INSERT INTO system_playlist_rotation_state ( user_id, playlist_kind, played_track_ids, rotation_started_at, updated_at ) VALUES ( sqlc.arg(user_id), sqlc.arg(playlist_kind), array_append('{}'::uuid[], sqlc.arg(track_id)::uuid), now(), now() ) ON CONFLICT (user_id, playlist_kind) DO UPDATE SET played_track_ids = CASE WHEN sqlc.arg(track_id)::uuid = ANY(system_playlist_rotation_state.played_track_ids) THEN system_playlist_rotation_state.played_track_ids ELSE array_append(system_playlist_rotation_state.played_track_ids, sqlc.arg(track_id)::uuid) END, updated_at = now(); -- name: GetRotationState :one SELECT * FROM system_playlist_rotation_state WHERE user_id = $1 AND playlist_kind = $2; -- name: ResetRotationState :exec -- Clears the played set and advances the rotation window. Called -- when the playlist snapshot has been fully sampled (Stage 2). UPDATE system_playlist_rotation_state SET played_track_ids = '{}', rotation_started_at = now(), updated_at = now() WHERE user_id = $1 AND playlist_kind = $2;