feat(recommendation): SuggestArtists service for M5c
Add per-user artist-suggestion service ranking out-of-library MBIDs by signal x similarity. Single-CTE SQL collects user likes (5x weight) and recency-decayed plays, joins against artist_similarity_unmatched, and filters in-library candidates plus non-terminal lidarr_requests. The service resolves top-3 attribution seeds to artist names in a batched GetArtistsByIDs call so the UI can render "because you liked X" reasons. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -69,6 +69,39 @@ func (q *Queries) GetArtistByName(ctx context.Context, name string) (Artist, err
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getArtistsByIDs = `-- name: GetArtistsByIDs :many
|
||||
SELECT id, name, sort_name, mbid, created_at, updated_at FROM artists WHERE id = ANY($1::uuid[])
|
||||
`
|
||||
|
||||
// Batched lookup used by M5c suggestion attribution to resolve top-3
|
||||
// contributing seed UUIDs back to artist names in one round-trip.
|
||||
func (q *Queries) GetArtistsByIDs(ctx context.Context, dollar_1 []pgtype.UUID) ([]Artist, error) {
|
||||
rows, err := q.db.Query(ctx, getArtistsByIDs, dollar_1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Artist
|
||||
for rows.Next() {
|
||||
var i Artist
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.SortName,
|
||||
&i.Mbid,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listArtists = `-- name: ListArtists :many
|
||||
SELECT id, name, sort_name, mbid, created_at, updated_at FROM artists ORDER BY sort_name
|
||||
`
|
||||
|
||||
Reference in New Issue
Block a user