feat(discover): show why each item is suggested
Each suggestion now carries the followed artists (seeds) that surfaced it, from DiscoverySeedContribution joined to the current watched roster (an unfollowed seed drops out), highest-scoring seed first. /discover renders "Similar to Arctic Monkeys, Coldplay +2" under each artist and album row — both kinds key off the candidate's artistMbid, so an album inherits its artist's seeds. web 187 tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,4 +21,33 @@ describe("discover feed API", () => {
|
||||
expect(body.albums.map((a: any) => a.album)).toEqual(["Rec"]);
|
||||
expect(body.artists[0]).toMatchObject({ artistMbid: "a2", seedCount: 2, sources: ["listenbrainz"] });
|
||||
});
|
||||
|
||||
it("annotates each suggestion with the followed-artist seeds that surfaced it", async () => {
|
||||
await prisma.watchedArtist.createMany({
|
||||
data: [
|
||||
{ mbid: "seed-am", name: "Arctic Monkeys" },
|
||||
{ mbid: "seed-cp", name: "Coldplay" },
|
||||
{ mbid: "seed-gone", name: "Unfollowed" },
|
||||
],
|
||||
});
|
||||
await prisma.discoverySuggestion.createMany({
|
||||
data: [
|
||||
{ kind: "artist", artistMbid: "cand1", artistName: "The Strokes", score: 0.9, seedCount: 2,
|
||||
sources: ["listenbrainz"], secondaryTypes: [], dedupeKey: "artist:cand1:" },
|
||||
{ kind: "album", artistMbid: "cand1", artistName: "The Strokes", rgMbid: "rgX", album: "Room on Fire",
|
||||
score: 0.7, seedCount: 2, sources: ["listenbrainz"], secondaryTypes: [], dedupeKey: "album:cand1:rgX" },
|
||||
],
|
||||
});
|
||||
await prisma.discoverySeedContribution.createMany({
|
||||
data: [
|
||||
{ candidateMbid: "cand1", candidateName: "The Strokes", seedMbid: "seed-am", score: 0.6, sources: ["listenbrainz"] },
|
||||
{ candidateMbid: "cand1", candidateName: "The Strokes", seedMbid: "seed-cp", score: 0.3, sources: ["listenbrainz"] },
|
||||
{ candidateMbid: "cand1", candidateName: "The Strokes", seedMbid: "no-such-seed", score: 0.9, sources: ["listenbrainz"] },
|
||||
],
|
||||
});
|
||||
const body = await (await GET()).json();
|
||||
// highest-scoring seed first; an unresolved/unfollowed seed is dropped
|
||||
expect(body.artists[0].seeds).toEqual(["Arctic Monkeys", "Coldplay"]);
|
||||
expect(body.albums[0].seeds).toEqual(["Arctic Monkeys", "Coldplay"]); // album inherits its artist's seeds
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user