6451cf3a3c
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
import { prisma } from "@/lib/db";
|
|
|
|
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 });
|
|
}
|
|
|
|
const created = await prisma.request.create({
|
|
data: {
|
|
artist: artist.trim(),
|
|
album: album.trim(),
|
|
job: { create: {} },
|
|
},
|
|
include: { job: true },
|
|
});
|
|
|
|
return Response.json(
|
|
{
|
|
id: created.id,
|
|
artist: created.artist,
|
|
album: created.album,
|
|
status: created.status,
|
|
job: { id: created.job!.id, state: created.job!.state, currentStage: created.job!.currentStage },
|
|
},
|
|
{ status: 201 },
|
|
);
|
|
}
|
|
|
|
export async function GET() {
|
|
const [requests, releases] = await Promise.all([
|
|
prisma.request.findMany({
|
|
orderBy: { createdAt: "desc" },
|
|
include: { job: { include: { candidates: { select: { source: true, format: true, trackCount: true, chosen: true } } } } },
|
|
}),
|
|
prisma.monitoredRelease.findMany({ select: { artistName: true, album: true, rgMbid: true } }),
|
|
]);
|
|
const rgByKey = new Map(releases.map((mr) => [`${mr.artistName} ${mr.album}`, mr.rgMbid]));
|
|
|
|
return Response.json({
|
|
requests: requests.map((r) => ({
|
|
id: r.id,
|
|
artist: r.artist,
|
|
album: r.album,
|
|
status: r.status,
|
|
createdAt: r.createdAt,
|
|
rgMbid: rgByKey.get(`${r.artist} ${r.album}`) ?? null,
|
|
job: r.job
|
|
? (() => {
|
|
const cands = r.job.candidates;
|
|
const chosen = cands.find((c) => c.chosen) ?? null;
|
|
return {
|
|
state: r.job.state,
|
|
currentStage: r.job.currentStage,
|
|
attempts: r.job.attempts,
|
|
error: r.job.error,
|
|
claimedAt: r.job.claimedAt,
|
|
updatedAt: r.job.updatedAt,
|
|
downloadProgress: r.job.downloadProgress,
|
|
paused: r.job.paused,
|
|
candidateCount: cands.length,
|
|
chosen: chosen ? { source: chosen.source, format: chosen.format, trackCount: chosen.trackCount } : null,
|
|
};
|
|
})()
|
|
: null,
|
|
})),
|
|
});
|
|
}
|