import { z } from "zod"; import { apiError, readJson, withApi } from "@/lib/api"; import { prisma } from "@/lib/db"; import { getNextEpisode, getProgress, moveToTrash, setStatus, updateEntryDetails, } from "@/lib/library"; const STATUSES = ["WATCHING", "PAUSED", "COMPLETED", "DROPPED", "WATCHLIST"] as const; /** GET /api/v1/bibliothek/{id} — ein Eintrag mit Fortschritt und nächster Episode. */ export const GET = withApi(async (_request, user, context) => { const { entryId } = await context.params; if (!entryId) return apiError("Es fehlt die Kennung des Eintrags.", 400); const entry = await prisma.libraryEntry.findFirst({ where: { id: entryId, userId: user.id }, include: { title: true, tags: { include: { tag: { select: { name: true } } } }, }, }); if (!entry) return apiError("Diesen Eintrag gibt es nicht.", 404); const [progress, next] = await Promise.all([ getProgress(user.id, entry.id), getNextEpisode(user.id, entry.id), ]); return { id: entry.id, status: entry.status, rating: entry.rating, notes: entry.notes, whereToWatch: entry.whereToWatch, owned: entry.owned, ownedSource: entry.ownedSource, favorite: entry.favorite, currentRun: entry.currentRun, tags: entry.tags.map((link) => link.tag.name), title: { id: entry.title.id, title: entry.title.title, type: entry.title.type, tmdbId: entry.title.tmdbId, year: entry.title.releaseDate?.getFullYear() ?? null, genres: entry.title.genres, }, progress, nextEpisode: next, }; }); const patchSchema = z.object({ status: z.enum(STATUSES).optional(), rating: z.number().int().min(1).max(10).nullable().optional(), notes: z.string().max(5000).nullable().optional(), whereToWatch: z.string().max(120).nullable().optional(), favorite: z.boolean().optional(), owned: z.boolean().optional(), ownedSource: z.string().max(80).nullable().optional(), }); /** PATCH /api/v1/bibliothek/{id} — Status und Angaben ändern. */ export const PATCH = withApi(async (request, user, context) => { const { entryId } = await context.params; if (!entryId) return apiError("Es fehlt die Kennung des Eintrags.", 400); const { status, ...details } = await readJson(request, patchSchema); if (status) await setStatus(user.id, entryId, status); if (Object.keys(details).length > 0) { await updateEntryDetails(user.id, entryId, details); } return { ok: true }; }); /** DELETE /api/v1/bibliothek/{id} — in den Papierkorb legen. */ export const DELETE = withApi(async (_request, user, context) => { const { entryId } = await context.params; if (!entryId) return apiError("Es fehlt die Kennung des Eintrags.", 400); await moveToTrash(user.id, entryId); return { ok: true, message: "In den Papierkorb gelegt." }; });