From 28c7773b40b519260d29b7178689558bf5e3325f Mon Sep 17 00:00:00 2001 From: Chandler Copeland Date: Mon, 6 Apr 2026 12:17:18 -0600 Subject: [PATCH] feat(18-02): GET and POST handlers at /api/templates - GET lists active templates (archivedAt IS NULL) with LEFT JOIN for formName - GET computes fieldCount server-side from signatureFields.length per D-12 - POST validates name + formTemplateId, verifies FK exists, returns 201 - Both handlers auth-gated with auth() per D-11 --- .../src/app/api/templates/route.ts | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 teressa-copeland-homes/src/app/api/templates/route.ts diff --git a/teressa-copeland-homes/src/app/api/templates/route.ts b/teressa-copeland-homes/src/app/api/templates/route.ts new file mode 100644 index 0000000..7a28a8a --- /dev/null +++ b/teressa-copeland-homes/src/app/api/templates/route.ts @@ -0,0 +1,68 @@ +import { auth } from '@/lib/auth'; +import { db } from '@/lib/db'; +import { documentTemplates, formTemplates } from '@/lib/db/schema'; +import type { SignatureFieldData } from '@/lib/db/schema'; +import { eq, isNull } from 'drizzle-orm'; + +export async function GET() { + const session = await auth(); + if (!session) return new Response('Unauthorized', { status: 401 }); + + const rows = await db + .select({ + id: documentTemplates.id, + name: documentTemplates.name, + formTemplateId: documentTemplates.formTemplateId, + formName: formTemplates.name, + signatureFields: documentTemplates.signatureFields, + createdAt: documentTemplates.createdAt, + updatedAt: documentTemplates.updatedAt, + }) + .from(documentTemplates) + .leftJoin(formTemplates, eq(documentTemplates.formTemplateId, formTemplates.id)) + .where(isNull(documentTemplates.archivedAt)); + + const result = rows.map((r) => ({ + id: r.id, + name: r.name, + formTemplateId: r.formTemplateId, + formName: r.formName, + fieldCount: ((r.signatureFields as SignatureFieldData[] | null) ?? []).length, + createdAt: r.createdAt, + updatedAt: r.updatedAt, + })); + + return Response.json(result); +} + +export async function POST(req: Request) { + const session = await auth(); + if (!session) return new Response('Unauthorized', { status: 401 }); + + const body = await req.json() as { name?: string; formTemplateId?: string }; + + if (!body.name || !body.formTemplateId) { + return Response.json( + { error: 'name and formTemplateId are required' }, + { status: 400 } + ); + } + + // Verify form template exists + const form = await db.query.formTemplates.findFirst({ + where: eq(formTemplates.id, body.formTemplateId), + }); + if (!form) { + return Response.json({ error: 'Form template not found' }, { status: 404 }); + } + + const [template] = await db + .insert(documentTemplates) + .values({ + name: body.name, + formTemplateId: body.formTemplateId, + }) + .returning(); + + return Response.json(template, { status: 201 }); +}