-- name: GetMostRecentPlaySessionForUser :one SELECT * FROM play_sessions WHERE user_id = $1 ORDER BY last_event_at DESC LIMIT 1; -- name: InsertPlaySession :one INSERT INTO play_sessions (user_id, started_at, last_event_at, client_id) VALUES ($1, $2, $2, $3) RETURNING *; -- name: TouchPlaySessionLastEvent :exec UPDATE play_sessions SET last_event_at = $2, track_count = track_count + 1 WHERE id = $1; -- name: GetOpenPlayEventForUser :one -- Returns the most recent play_event for a user where ended_at IS NULL. -- Used by the auto-close-prior step in playevents.RecordPlayStarted. SELECT * FROM play_events WHERE user_id = $1 AND ended_at IS NULL ORDER BY started_at DESC LIMIT 1; -- name: InsertPlayEvent :one INSERT INTO play_events ( user_id, track_id, session_id, started_at, client_id ) VALUES ($1, $2, $3, $4, $5) RETURNING *; -- name: UpdatePlayEventEnded :one -- Closes a play_event by id with the given ended_at, duration, and skip flag. -- completion_ratio is computed from duration_played_ms and the track duration -- (looked up by the caller — sqlc doesn't do joins on UPDATE). UPDATE play_events SET ended_at = $2, duration_played_ms = $3, completion_ratio = $4, was_skipped = $5 WHERE id = $1 RETURNING *; -- name: GetPlayEventByID :one SELECT * FROM play_events WHERE id = $1; -- name: InsertSkipEvent :one INSERT INTO skip_events (user_id, track_id, session_id, skipped_at, position_ms) VALUES ($1, $2, $3, $4, $5) RETURNING *; -- name: ListRecentSessionTracks :many -- Returns up to $3 tracks in session $1 whose play_event started before -- $2, ordered newest-first. Used by playevents.RecordPlayStarted to -- build the session_vector for the just-inserted play_event. SELECT t.* FROM tracks t JOIN play_events pe ON pe.track_id = t.id WHERE pe.session_id = $1 AND pe.started_at < $2 ORDER BY pe.started_at DESC LIMIT $3; -- name: UpdatePlayEventVector :exec -- Used right after InsertPlayEvent to populate session_vector_at_play -- once the vector has been computed. UPDATE play_events SET session_vector_at_play = $2 WHERE id = $1; -- name: GetCurrentSessionVectorForUser :one -- Returns the session_vector_at_play of the user's most recent play_event -- in a still-active (un-timed-out) session. NoRows means no current vector. -- Joined with play_sessions so closed sessions don't leak stale vectors. SELECT pe.session_vector_at_play FROM play_events pe JOIN play_sessions s ON s.id = pe.session_id WHERE pe.user_id = $1 AND s.ended_at IS NULL ORDER BY pe.started_at DESC LIMIT 1;