feat(server/m7-352): BuildSystemPlaylists with atomic replace + concurrency guard

Implements T5 of #352 slice 2: adds CreateSystemPlaylist sqlc query,
BuildSystemPlaylists function (For-You + Songs-like mixes, tx atomic
replace, in_flight guard, tieBreakHash determinism), and 7 integration
tests covering activity, quarantine exclusion, atomic replace, concurrency,
daily nonce stability, ListActiveUsers, and stale-in-flight recovery.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-04 08:35:02 -04:00
parent ef478778ef
commit 46a9de8e9a
4 changed files with 668 additions and 0 deletions
+46
View File
@@ -23,6 +23,52 @@ func (q *Queries) ClearStaleSystemPlaylistInFlight(ctx context.Context) error {
return err
}
const createSystemPlaylist = `-- name: CreateSystemPlaylist :one
INSERT INTO playlists (
user_id, name, description, is_public,
kind, system_variant, seed_artist_id, cover_path
) VALUES ($1, $2, '', false, 'system', $3, $4, $5)
RETURNING id, user_id, name, description, is_public, cover_path, track_count, duration_sec, created_at, updated_at, kind, system_variant, seed_artist_id
`
type CreateSystemPlaylistParams struct {
UserID pgtype.UUID
Name string
SystemVariant *string
SeedArtistID pgtype.UUID
CoverPath *string
}
// Inserts a system-generated playlist. Used by BuildSystemPlaylists.
// For 'for_you' variant, pass seed_artist_id as NULL (zero-value pgtype.UUID
// with Valid=false).
func (q *Queries) CreateSystemPlaylist(ctx context.Context, arg CreateSystemPlaylistParams) (Playlist, error) {
row := q.db.QueryRow(ctx, createSystemPlaylist,
arg.UserID,
arg.Name,
arg.SystemVariant,
arg.SeedArtistID,
arg.CoverPath,
)
var i Playlist
err := row.Scan(
&i.ID,
&i.UserID,
&i.Name,
&i.Description,
&i.IsPublic,
&i.CoverPath,
&i.TrackCount,
&i.DurationSec,
&i.CreatedAt,
&i.UpdatedAt,
&i.Kind,
&i.SystemVariant,
&i.SeedArtistID,
)
return i, err
}
const deleteSystemPlaylistsForUser = `-- name: DeleteSystemPlaylistsForUser :exec
DELETE FROM playlists WHERE user_id = $1 AND kind = 'system'
`