import { applyVerdict, undoLastVerdict } from "@/lib/verdict"; import { addVocab } from "@/lib/vocab"; import { isMode, type VerdictBody } from "@/lib/types"; export const dynamic = "force-dynamic"; export async function POST(request: Request) { let body: VerdictBody & { undo?: boolean }; try { body = (await request.json()) as VerdictBody & { undo?: boolean }; } catch { return Response.json({ error: "bad json" }, { status: 400 }); } // Undo takes no key: it puts back the LAST verdict, whatever it was. Anything // else would need the client to know which of several piles a verdict moved a // key between, which is precisely the knowledge the journal exists to hold. if (body?.undo) { const out = await undoLastVerdict(); if (!out.ok) return Response.json({ error: out.error }, { status: 400 }); return Response.json(out); } if (!body?.key || !isMode(body.mode) || !Number.isInteger(body.verdict)) { return Response.json({ error: "key, mode and verdict are required" }, { status: 400 }); } // A custom word joins the vocabulary BEFORE the verdict lands, so it is // offered on the next clip even if the verdict write then fails. if (body.custom && body.word) await addVocab(body.word); try { return Response.json(await applyVerdict(body)); } catch (err) { return Response.json({ error: String((err as Error)?.message ?? err) }, { status: 500 }); } }