fix(recommendation): broaden You-might-like fallback to liked album/track artists (#790)
The fallback pulled artists only from explicit artist-likes (general_likes_artists),
but most users like albums and tracks far more than artists — so the artists row
still came up thin (a couple of tiles) even with a rich library, while the albums
row filled fine.
Broaden both fallbacks to "entities you've shown affinity for":
- artist fallback = explicit artist-likes ∪ artists of liked albums ∪ artists of
liked tracks.
- album fallback = explicit album-likes ∪ albums of liked tracks.
New dedicated queries (ListYouMightLike{Artist,Album}FallbackForUser) replace the
narrow Rediscover-fallback reuse; same projection so the Go layer still converts
directly. (Aliased + fully-qualified the UNION arms — sqlc merges UNION scopes,
so unqualified user_id was ambiguous across the three like tables.)
Test: 12 liked TRACKS by distinct artists, no artist-likes → the artist row now
fills from their artists (was empty before).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -48,6 +48,40 @@ func TestHomeData_YouMightLike_FallbackFillsFromLikedArtists(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestHomeData_YouMightLike_FallbackFromLikedTrackArtists: the broad fallback
|
||||
// must surface the artists of LIKED TRACKS even with no explicit artist-likes
|
||||
// (most users like tracks/albums, rarely artists). 12 liked tracks by distinct
|
||||
// artists, no artist-likes, no plays → the artist row fills from them.
|
||||
func TestHomeData_YouMightLike_FallbackFromLikedTrackArtists(t *testing.T) {
|
||||
pool := newPool(t)
|
||||
user := seedUser(t, pool, "home-yml-trackartists")
|
||||
fromLiked := make(map[pgtype.UUID]bool, 12)
|
||||
for i := 0; i < 12; i++ {
|
||||
a := seedArtist(t, pool, fmt.Sprintf("TrkArtist%02d", i), "")
|
||||
al := seedAlbumForArtist(t, pool, a.ID, fmt.Sprintf("Alb%02d", i))
|
||||
tr := seedTrackOnAlbum(t, pool, al.ID, a.ID, fmt.Sprintf("Trk%02d", i))
|
||||
if _, err := pool.Exec(context.Background(),
|
||||
`INSERT INTO general_likes (user_id, track_id) VALUES ($1, $2)`, user.ID, tr.ID); err != nil {
|
||||
t.Fatalf("like track: %v", err)
|
||||
}
|
||||
fromLiked[a.ID] = true
|
||||
}
|
||||
|
||||
got, err := HomeData(context.Background(), pool, user.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("HomeData: %v", err)
|
||||
}
|
||||
if len(got.YouMightLikeArtists) != HomeYouMightLikeLimit {
|
||||
t.Fatalf("you-might-like artists = %d, want %d (from liked-track artists)",
|
||||
len(got.YouMightLikeArtists), HomeYouMightLikeLimit)
|
||||
}
|
||||
for _, r := range got.YouMightLikeArtists {
|
||||
if !fromLiked[r.Artist.ID] {
|
||||
t.Errorf("artist %s not from the liked-track pool", r.Artist.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHomeData_NewUser_AllSectionsEmpty(t *testing.T) {
|
||||
pool := newPool(t)
|
||||
user := seedUser(t, pool, "home-newuser")
|
||||
|
||||
Reference in New Issue
Block a user