From 87a51fbce7d12bb60a5716d72f5d63a3e57078fb Mon Sep 17 00:00:00 2001 From: sjcoetzeesj-coder Date: Wed, 16 Sep 2026 14:30:46 +0200 Subject: [PATCH] feat(notes): add PATCH + DELETE /api/notes/[id] handlers --- Workflow/app/api/notes/[id]/route.ts | 71 ++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 Workflow/app/api/notes/[id]/route.ts diff --git a/Workflow/app/api/notes/[id]/route.ts b/Workflow/app/api/notes/[id]/route.ts new file mode 100644 index 0000000..66e95d7 --- /dev/null +++ b/Workflow/app/api/notes/[id]/route.ts @@ -0,0 +1,71 @@ +// app/api/notes/[id]/route.ts +// PATCH /api/notes/[id] — update an existing note (edit text, toggle done). +// DELETE /api/notes/[id] — delete a note. +// Hardcoded collection = "ysterbaard_notes". Field-allowlisted. + +import { NextRequest, NextResponse } from "next/server"; +import { updateRecord, deleteRecord } from "@/lib/pb"; +import type { YsterbaardNote } from "@/lib/types"; + +export const dynamic = "force-dynamic"; + +const COLLECTION = "ysterbaard_notes"; +const FIELD_ALLOWLIST = ["title", "content", "is_done", "done_at"] as const; + +export async function PATCH( + req: NextRequest, + { params }: { params: { id: string } }, +) { + const id = params.id; + let body: Record; + try { + body = await req.json(); + } catch { + return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 }); + } + + const sanitised: Record = {}; + + if (typeof body.title === "string") { + const t = body.title.trim(); + if (!t) return NextResponse.json({ error: "title cannot be empty" }, { status: 400 }); + sanitised.title = t; + } + if (typeof body.content === "string") { + sanitised.content = body.content.trim(); + } + + if (typeof body.is_done === "boolean") { + sanitised.is_done = body.is_done; + sanitised.done_at = body.is_done ? new Date().toISOString() : null; + } + + // Refuse empty patches so we don't issue pointless PATCH calls. + if (Object.keys(sanitised).length === 0) { + return NextResponse.json({ error: "no editable fields supplied" }, { status: 400 }); + } + + try { + const updated = await updateRecord(COLLECTION, id, sanitised); + return NextResponse.json(updated, { status: 200 }); + } catch (err) { + const message = err instanceof Error ? err.message : "Unknown PB error"; + console.error("[notes patch]", id, message); + return NextResponse.json({ error: message }, { status: 502 }); + } +} + +export async function DELETE( + _req: NextRequest, + { params }: { params: { id: string } }, +) { + const id = params.id; + try { + await deleteRecord(COLLECTION, id); + return NextResponse.json({ ok: true }, { status: 200 }); + } catch (err) { + const message = err instanceof Error ? err.message : "Unknown PB error"; + console.error("[notes delete]", id, message); + return NextResponse.json({ error: message }, { status: 502 }); + } +} \ No newline at end of file