Files
minstrel/internal/db/dbq/you_might_like.sql.go
T
bvandeusenandClaude Opus 5.5 1d4ef1a23f docs: query comments say what each query selects and why, not how it came to be (#6277)
Rewrites the internal/db/queries comments to rule 32 and regenerates
dbq, whose doc comments and embedded SQL carry them. The bugs behind the
tiered mixes, the md5 order seed, the score bands and the round-robin
arms are restated as the constraint each one enforces; counts from one
library and stale cross-references are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 12:31:13 -04:00

368 lines
12 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: you_might_like.sql
package dbq
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const countListeningSignalForUser = `-- name: CountListeningSignalForUser :one
SELECT
count(DISTINCT pe.track_id)::bigint AS distinct_tracks,
count(DISTINCT t.artist_id)::bigint AS distinct_artists
FROM play_events pe
JOIN tracks t ON t.id = pe.track_id
WHERE pe.user_id = $1 AND pe.was_skipped = false
`
type CountListeningSignalForUserRow struct {
DistinctTracks int64
DistinctArtists int64
}
// "You might like" Home rows. The daily build computes ranked
// album/artist IDs in Go (similarity roll-up + cold-start gate) and
// atomic-replaces them here; /api/home reads them back hydrated.
// Cold-start gate. Returns the breadth of the user's real listening:
// distinct unskipped tracks played and distinct artists played. The
// build skips You-might-like entirely below a threshold (a thin history
// yields near-random roll-ups). was_skipped=false so a user spamming
// next can't inflate the signal.
func (q *Queries) CountListeningSignalForUser(ctx context.Context, userID pgtype.UUID) (CountListeningSignalForUserRow, error) {
row := q.db.QueryRow(ctx, countListeningSignalForUser, userID)
var i CountListeningSignalForUserRow
err := row.Scan(&i.DistinctTracks, &i.DistinctArtists)
return i, err
}
const deleteYouMightLikeAlbumsForUser = `-- name: DeleteYouMightLikeAlbumsForUser :exec
DELETE FROM you_might_like_albums WHERE user_id = $1
`
func (q *Queries) DeleteYouMightLikeAlbumsForUser(ctx context.Context, userID pgtype.UUID) error {
_, err := q.db.Exec(ctx, deleteYouMightLikeAlbumsForUser, userID)
return err
}
const deleteYouMightLikeArtistsForUser = `-- name: DeleteYouMightLikeArtistsForUser :exec
DELETE FROM you_might_like_artists WHERE user_id = $1
`
func (q *Queries) DeleteYouMightLikeArtistsForUser(ctx context.Context, userID pgtype.UUID) error {
_, err := q.db.Exec(ctx, deleteYouMightLikeArtistsForUser, userID)
return err
}
const insertYouMightLikeAlbum = `-- name: InsertYouMightLikeAlbum :exec
INSERT INTO you_might_like_albums (user_id, album_id, rank)
VALUES ($1, $2, $3)
`
type InsertYouMightLikeAlbumParams struct {
UserID pgtype.UUID
AlbumID pgtype.UUID
Rank int32
}
func (q *Queries) InsertYouMightLikeAlbum(ctx context.Context, arg InsertYouMightLikeAlbumParams) error {
_, err := q.db.Exec(ctx, insertYouMightLikeAlbum, arg.UserID, arg.AlbumID, arg.Rank)
return err
}
const insertYouMightLikeArtist = `-- name: InsertYouMightLikeArtist :exec
INSERT INTO you_might_like_artists (user_id, artist_id, rank)
VALUES ($1, $2, $3)
`
type InsertYouMightLikeArtistParams struct {
UserID pgtype.UUID
ArtistID pgtype.UUID
Rank int32
}
func (q *Queries) InsertYouMightLikeArtist(ctx context.Context, arg InsertYouMightLikeArtistParams) error {
_, err := q.db.Exec(ctx, insertYouMightLikeArtist, arg.UserID, arg.ArtistID, arg.Rank)
return err
}
const listYouMightLikeAlbumFallbackForUser = `-- name: ListYouMightLikeAlbumFallbackForUser :many
WITH liked_album_ids AS (
SELECT likb.album_id AS album_id
FROM general_likes_albums likb
WHERE likb.user_id = $1
UNION
SELECT trk.album_id AS album_id
FROM general_likes likt
JOIN tracks trk ON trk.id = likt.track_id
WHERE likt.user_id = $1
)
SELECT albums.id, albums.title, albums.sort_title, albums.artist_id, albums.release_date, albums.mbid, albums.cover_art_path, albums.created_at, albums.updated_at, albums.cover_art_source, albums.cover_art_sources_version, albums.release_group_mbid, artists.name AS artist_name
FROM liked_album_ids lai
JOIN albums ON albums.id = lai.album_id
JOIN artists ON artists.id = albums.artist_id
ORDER BY md5(albums.id::text || current_date::text)
LIMIT $2
`
type ListYouMightLikeAlbumFallbackForUserParams struct {
UserID pgtype.UUID
Limit int32
}
type ListYouMightLikeAlbumFallbackForUserRow struct {
Album Album
ArtistName string
}
// Broad "albums you've shown affinity for" pool: explicitly liked albums PLUS
// the albums of liked tracks. Same projection as ListYouMightLikeAlbumsForUser.
func (q *Queries) ListYouMightLikeAlbumFallbackForUser(ctx context.Context, arg ListYouMightLikeAlbumFallbackForUserParams) ([]ListYouMightLikeAlbumFallbackForUserRow, error) {
rows, err := q.db.Query(ctx, listYouMightLikeAlbumFallbackForUser, arg.UserID, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListYouMightLikeAlbumFallbackForUserRow
for rows.Next() {
var i ListYouMightLikeAlbumFallbackForUserRow
if err := rows.Scan(
&i.Album.ID,
&i.Album.Title,
&i.Album.SortTitle,
&i.Album.ArtistID,
&i.Album.ReleaseDate,
&i.Album.Mbid,
&i.Album.CoverArtPath,
&i.Album.CreatedAt,
&i.Album.UpdatedAt,
&i.Album.CoverArtSource,
&i.Album.CoverArtSourcesVersion,
&i.Album.ReleaseGroupMbid,
&i.ArtistName,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listYouMightLikeAlbumsForUser = `-- name: ListYouMightLikeAlbumsForUser :many
SELECT albums.id, albums.title, albums.sort_title, albums.artist_id, albums.release_date, albums.mbid, albums.cover_art_path, albums.created_at, albums.updated_at, albums.cover_art_source, albums.cover_art_sources_version, albums.release_group_mbid, artists.name AS artist_name
FROM you_might_like_albums yml
JOIN albums ON albums.id = yml.album_id
JOIN artists ON artists.id = albums.artist_id
WHERE yml.user_id = $1
ORDER BY yml.rank
LIMIT $2
`
type ListYouMightLikeAlbumsForUserParams struct {
UserID pgtype.UUID
Limit int32
}
type ListYouMightLikeAlbumsForUserRow struct {
Album Album
ArtistName string
}
// Read path. Same projection as ListRediscoverAlbumsForUser so the API
// layer reuses albumRefFrom(row.Album, row.ArtistName, …). Ordered by
// the rank persisted at build time. Final cross-section dedup (vs Most
// Played / Rediscover) and the output cap land in the Go layer
// (internal/recommendation/home.go).
func (q *Queries) ListYouMightLikeAlbumsForUser(ctx context.Context, arg ListYouMightLikeAlbumsForUserParams) ([]ListYouMightLikeAlbumsForUserRow, error) {
rows, err := q.db.Query(ctx, listYouMightLikeAlbumsForUser, arg.UserID, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListYouMightLikeAlbumsForUserRow
for rows.Next() {
var i ListYouMightLikeAlbumsForUserRow
if err := rows.Scan(
&i.Album.ID,
&i.Album.Title,
&i.Album.SortTitle,
&i.Album.ArtistID,
&i.Album.ReleaseDate,
&i.Album.Mbid,
&i.Album.CoverArtPath,
&i.Album.CreatedAt,
&i.Album.UpdatedAt,
&i.Album.CoverArtSource,
&i.Album.CoverArtSourcesVersion,
&i.Album.ReleaseGroupMbid,
&i.ArtistName,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listYouMightLikeArtistFallbackForUser = `-- name: ListYouMightLikeArtistFallbackForUser :many
WITH liked_artist_ids AS (
SELECT lika.artist_id AS artist_id
FROM general_likes_artists lika
WHERE lika.user_id = $1
UNION
SELECT alb.artist_id AS artist_id
FROM general_likes_albums likb
JOIN albums alb ON alb.id = likb.album_id
WHERE likb.user_id = $1
UNION
SELECT trk.artist_id AS artist_id
FROM general_likes likt
JOIN tracks trk ON trk.id = likt.track_id
WHERE likt.user_id = $1
)
SELECT artists.id, artists.name, artists.sort_name, artists.mbid, artists.created_at, artists.updated_at, artists.artist_thumb_path, artists.artist_fanart_path, artists.artist_art_source, artists.artist_art_sources_version,
cov.id AS cover_album_id,
cnt.album_count::bigint AS album_count
FROM liked_artist_ids lai
JOIN artists ON artists.id = lai.artist_id
LEFT JOIN LATERAL (
SELECT id FROM albums
WHERE artist_id = artists.id AND cover_art_path IS NOT NULL
ORDER BY created_at DESC LIMIT 1
) cov ON true
LEFT JOIN LATERAL (
SELECT count(*) AS album_count
FROM albums WHERE artist_id = artists.id
) cnt ON true
ORDER BY md5(artists.id::text || current_date::text)
LIMIT $2
`
type ListYouMightLikeArtistFallbackForUserParams struct {
UserID pgtype.UUID
Limit int32
}
type ListYouMightLikeArtistFallbackForUserRow struct {
Artist Artist
CoverAlbumID pgtype.UUID
AlbumCount int64
}
// Broad "artists you've shown affinity for" pool to fill a thin
// You-might-like artists row: explicitly liked artists PLUS the artists of
// liked albums and liked tracks. Most users like albums/tracks far more than
// they like artists explicitly, so the union is much deeper than
// general_likes_artists alone. Daily-stable order; same projection as
// ListYouMightLikeArtistsForUser so the Go layer reuses it directly.
func (q *Queries) ListYouMightLikeArtistFallbackForUser(ctx context.Context, arg ListYouMightLikeArtistFallbackForUserParams) ([]ListYouMightLikeArtistFallbackForUserRow, error) {
rows, err := q.db.Query(ctx, listYouMightLikeArtistFallbackForUser, arg.UserID, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListYouMightLikeArtistFallbackForUserRow
for rows.Next() {
var i ListYouMightLikeArtistFallbackForUserRow
if err := rows.Scan(
&i.Artist.ID,
&i.Artist.Name,
&i.Artist.SortName,
&i.Artist.Mbid,
&i.Artist.CreatedAt,
&i.Artist.UpdatedAt,
&i.Artist.ArtistThumbPath,
&i.Artist.ArtistFanartPath,
&i.Artist.ArtistArtSource,
&i.Artist.ArtistArtSourcesVersion,
&i.CoverAlbumID,
&i.AlbumCount,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listYouMightLikeArtistsForUser = `-- name: ListYouMightLikeArtistsForUser :many
SELECT artists.id, artists.name, artists.sort_name, artists.mbid, artists.created_at, artists.updated_at, artists.artist_thumb_path, artists.artist_fanart_path, artists.artist_art_source, artists.artist_art_sources_version,
cov.id AS cover_album_id,
cnt.album_count::bigint AS album_count
FROM you_might_like_artists yml
JOIN artists ON artists.id = yml.artist_id
LEFT JOIN LATERAL (
SELECT id FROM albums
WHERE artist_id = artists.id AND cover_art_path IS NOT NULL
ORDER BY created_at DESC LIMIT 1
) cov ON true
LEFT JOIN LATERAL (
SELECT count(*) AS album_count
FROM albums WHERE artist_id = artists.id
) cnt ON true
WHERE yml.user_id = $1
ORDER BY yml.rank
LIMIT $2
`
type ListYouMightLikeArtistsForUserParams struct {
UserID pgtype.UUID
Limit int32
}
type ListYouMightLikeArtistsForUserRow struct {
Artist Artist
CoverAlbumID pgtype.UUID
AlbumCount int64
}
// Read path. Same projection as ListRediscoverArtistsForUser (embeds the
// artist + a representative cover_album_id + album_count) so the API
// layer reuses artistRefFromCovered. Ordered by persisted rank.
func (q *Queries) ListYouMightLikeArtistsForUser(ctx context.Context, arg ListYouMightLikeArtistsForUserParams) ([]ListYouMightLikeArtistsForUserRow, error) {
rows, err := q.db.Query(ctx, listYouMightLikeArtistsForUser, arg.UserID, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListYouMightLikeArtistsForUserRow
for rows.Next() {
var i ListYouMightLikeArtistsForUserRow
if err := rows.Scan(
&i.Artist.ID,
&i.Artist.Name,
&i.Artist.SortName,
&i.Artist.Mbid,
&i.Artist.CreatedAt,
&i.Artist.UpdatedAt,
&i.Artist.ArtistThumbPath,
&i.Artist.ArtistFanartPath,
&i.Artist.ArtistArtSource,
&i.Artist.ArtistArtSourcesVersion,
&i.CoverAlbumID,
&i.AlbumCount,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}