feat: wanted list API — list + standalone add

This commit is contained in:
Jonathan
2026-07-11 14:04:35 +02:00
parent 6615ecf3a7
commit cd652c7285
2 changed files with 116 additions and 0 deletions
+62
View File
@@ -0,0 +1,62 @@
import { prisma } from "@/lib/db";
import { searchReleaseGroup } from "@/lib/musicbrainz";
export async function GET() {
const items = await prisma.monitoredRelease.findMany({
where: { monitored: true, state: { not: "fulfilled" } },
orderBy: [{ lastSearchedAt: { sort: "asc", nulls: "first" } }, { createdAt: "asc" }],
});
return Response.json({
wanted: items.map((r) => ({
id: r.id,
artistName: r.artistName,
album: r.album,
state: r.state,
currentQualityClass: r.currentQualityClass,
lastSearchedAt: r.lastSearchedAt,
watchedArtistId: r.watchedArtistId,
})),
});
}
export async function POST(request: Request) {
let body: unknown;
try {
body = await request.json();
} catch {
return Response.json({ error: "invalid JSON" }, { status: 400 });
}
const { artist, album } = (body ?? {}) as { artist?: unknown; album?: unknown };
if (typeof artist !== "string" || !artist.trim() || typeof album !== "string" || !album.trim()) {
return Response.json({ error: "artist and album are required" }, { status: 400 });
}
let match;
try {
match = await searchReleaseGroup(artist.trim(), album.trim());
} catch {
return Response.json({ error: "MusicBrainz unavailable" }, { status: 502 });
}
if (!match) {
return Response.json({ error: "no matching release-group found" }, { status: 404 });
}
const existing = await prisma.monitoredRelease.findUnique({ where: { rgMbid: match.rgMbid } });
if (existing) {
const updated = await prisma.monitoredRelease.update({ where: { rgMbid: match.rgMbid }, data: { monitored: true } });
return Response.json({ id: updated.id, album: updated.album, monitored: updated.monitored }, { status: 200 });
}
const created = await prisma.monitoredRelease.create({
data: {
artistMbid: match.artistMbid,
artistName: match.artistName,
rgMbid: match.rgMbid,
album: match.title,
primaryType: match.primaryType,
secondaryTypes: match.secondaryTypes,
firstReleaseDate: match.firstReleaseDate,
monitored: true,
},
});
return Response.json({ id: created.id, album: created.album, monitored: created.monitored }, { status: 201 });
}