ListRecentSessionTracks + UpdatePlayEventVector for the vector capture
path inside RecordPlayStarted. LikeTrack switches to :execrows so the
contextual-likes capture can detect insert vs already-exists. Existing
callers updated to ignore the count for now; later tasks consume it.
Table was referenced in migration 0005's comment but never created —
this slice fills the gap. Soft-delete via deleted_at column; hot-path
partial index on active rows; GIN index on session_vector for
M3 sub-plan #3's similarity queries.
Single SELECT that joins tracks with general_likes (for is_liked) and
an aggregated LATERAL subquery on play_events (for last_played_at,
play_count, skip_count). Excludes seed + tracks played in the last
N hours. Drives the M3 weighted shuffle scoring.
Three tables keyed on (user_id, entity_id) with liked_at. Per-table
indexes on (user_id, liked_at DESC) for the recently-liked feed.
sqlc queries cover like/unlike/list-rows/count/list-ids per entity.
Tables and indexes per spec §5. session_vector_at_play ships nullable
so M3 doesn't need a follow-up migration. Table is named play_sessions
to avoid collision with the existing sessions (HTTP auth) table from
migration 0004.
Resolves /api/* callers from session cookie first, Authorization
bearer second. Touches last_seen on success for future active-
sessions UI. Adds GetUserByID query used by the middleware.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds ListAlbumsAlphaByName, ListAlbumsAlphaByArtist (with sqlc.embed
for the joined artist sort_name), ListAlbumsNewest, ListAlbumsRandom,
ListAlbumsByGenre, and SearchAlbums. Powers getAlbumList2 type filters
and the album facet of search3.