Files
minstrel/internal/recommendation/sessionvector.go
T
bvandeusen 627b7d1be5 feat(recommendation): add BuildSessionVector pure function
Pure aggregation per spec §6: Seed flag (true when prior < 3),
deduplicated Artists ordered by first appearance, Tags bag-of-counts
from tracks.genre (empty genres skipped), RecentTrackIDs preserving
input order. JSON round-trip verified.
2026-04-27 11:17:11 -04:00

44 lines
1010 B
Go

package recommendation
import (
"github.com/jackc/pgx/v5/pgtype"
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
)
type SessionVector struct {
Seed bool `json:"seed"`
Artists []string `json:"artists"`
Tags map[string]int `json:"tags"`
RecentTrackIDs []string `json:"recent_track_ids"`
}
func BuildSessionVector(priorTracks []dbq.Track) SessionVector {
v := SessionVector{
Seed: len(priorTracks) < 3,
Artists: []string{},
Tags: map[string]int{},
RecentTrackIDs: []string{},
}
seen := map[string]bool{}
for _, t := range priorTracks {
artistID := uuidString(t.ArtistID)
if !seen[artistID] {
seen[artistID] = true
v.Artists = append(v.Artists, artistID)
}
if t.Genre != nil && *t.Genre != "" {
v.Tags[*t.Genre]++
}
v.RecentTrackIDs = append(v.RecentTrackIDs, uuidString(t.ID))
}
return v
}
func uuidString(u pgtype.UUID) string {
if !u.Valid {
return ""
}
return u.String()
}