From cd8787b77dadf752826a967d404b718b3ec92601 Mon Sep 17 00:00:00 2001 From: yyamashita Date: Sat, 9 May 2026 11:21:28 +0900 Subject: Add JSON API endpoints and CLI script for band/artist management Co-Authored-By: Claude Sonnet 4.6 --- app/routes/api-bands.tsx | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 app/routes/api-bands.tsx (limited to 'app/routes/api-bands.tsx') diff --git a/app/routes/api-bands.tsx b/app/routes/api-bands.tsx new file mode 100644 index 0000000..64a9269 --- /dev/null +++ b/app/routes/api-bands.tsx @@ -0,0 +1,51 @@ +import type { ActionFunctionArgs } from "react-router"; +import { createBand, getIpAddress, listBands, toSlug } from "~/lib/db.server"; + +export function loader() { + return Response.json(listBands()); +} + +export async function action({ request }: ActionFunctionArgs) { + if (request.method !== "POST") { + return Response.json({ error: "Method not allowed" }, { status: 405 }); + } + + let body: Record; + try { + body = await request.json(); + } catch { + return Response.json({ error: "Invalid JSON body" }, { status: 400 }); + } + + const name = (body.name as string | undefined)?.trim(); + if (!name) return Response.json({ error: "name is required" }, { status: 400 }); + + const slug = (body.slug as string | undefined)?.trim() || toSlug(name); + if (!slug) return Response.json({ error: "could not derive slug from name" }, { status: 400 }); + + const id = crypto.randomUUID(); + try { + const band = createBand({ + id, + slug, + name, + area: (body.area as string) || null, + description: (body.description as string) || null, + status: (body.status as string) || "active", + links: (body.links as { label: string; url: string }[]) || [], + artists: (body.artists as { id: string; role: string | null }[]) || [], + message: (body.message as string) || "API import", + ip_address: getIpAddress(request), + }); + return Response.json(band, { status: 201 }); + } catch (e) { + if (e instanceof Error && e.message.includes("UNIQUE constraint failed: bands.slug")) { + return Response.json({ error: "slug already in use" }, { status: 409 }); + } + throw e; + } +} + +export default function () { + return null; +} -- cgit v1.2.3