feat(web): Library page — owned-albums grid with cover art

New /library: GET /api/library lists LibraryItems enriched with rgMbid + year
from the matching MonitoredRelease. Client renders a cover-art grid with a live
filter; clicking an album opens the AlbumModal (tracklist). Added Library to the
nav. The album-only overview to see everything downloaded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan
2026-07-12 15:24:16 +02:00
parent d05d092d53
commit 4f6c5995f8
6 changed files with 123 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
import { describe, it, expect } from "vitest";
import { prisma } from "@/lib/db";
import { GET } from "./route";
describe("library API", () => {
it("lists owned albums enriched with rgMbid + year from the matching release", async () => {
await prisma.monitoredRelease.create({
data: {
artistMbid: "a1", artistName: "Radiohead", rgMbid: "rg-inrainbows", album: "In Rainbows",
primaryType: "Album", firstReleaseDate: "2007-10-10", monitored: true, state: "fulfilled",
},
});
await prisma.libraryItem.create({
data: { artist: "Radiohead", album: "In Rainbows", path: "/m", source: "qobuz", format: "FLAC", qualityClass: 3 },
});
await prisma.libraryItem.create({
data: { artist: "Unknown", album: "Bootleg", path: "/m", source: "scan", format: "MP3", qualityClass: 1 },
});
const res = await GET();
expect(res.status).toBe(200);
const { albums } = await res.json();
expect(albums).toHaveLength(2);
const inr = albums.find((a: { album: string }) => a.album === "In Rainbows");
expect(inr).toMatchObject({ artist: "Radiohead", rgMbid: "rg-inrainbows", year: "2007", format: "FLAC", qualityClass: 3 });
const boot = albums.find((a: { album: string }) => a.album === "Bootleg");
expect(boot).toMatchObject({ rgMbid: null, year: null }); // no matching release → no art/tracks
});
});