feat(recommendation): add LoadCandidates DB-backed loader
Wraps the LoadRadioCandidates sqlc query, projects rows to []Candidate. Live-DB tests verify seed exclusion, recently-played exclusion, stat-join correctness (likes + plays + skips + last_played_at), and cross-user isolation.
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
package recommendation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
|
||||
)
|
||||
|
||||
func LoadCandidates(
|
||||
ctx context.Context,
|
||||
q *dbq.Queries,
|
||||
userID, seedID pgtype.UUID,
|
||||
recentlyPlayedHours int,
|
||||
) ([]Candidate, error) {
|
||||
rows, err := q.LoadRadioCandidates(ctx, dbq.LoadRadioCandidatesParams{
|
||||
UserID: userID,
|
||||
ID: seedID,
|
||||
Column3: float64(recentlyPlayedHours),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]Candidate, 0, len(rows))
|
||||
for _, r := range rows {
|
||||
var lpt *time.Time
|
||||
if r.LastPlayedAt.Valid {
|
||||
t := r.LastPlayedAt.Time
|
||||
lpt = &t
|
||||
}
|
||||
out = append(out, Candidate{
|
||||
Track: r.Track,
|
||||
Inputs: ScoringInputs{
|
||||
IsGeneralLiked: r.IsLiked,
|
||||
LastPlayedAt: lpt,
|
||||
PlayCount: int(r.PlayCount),
|
||||
SkipCount: int(r.SkipCount),
|
||||
},
|
||||
})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
Reference in New Issue
Block a user