import { NextRequest, NextResponse } from "next/server"; import { Prisma } from "@/generated/prisma/client"; import { prisma } from "@/lib/db"; import { requireApiAuthWithOrg, handleApiError } from "@/lib/api-auth"; export async function GET(request: NextRequest) { try { const session = await requireApiAuthWithOrg(); const { searchParams } = new URL(request.url); if (searchParams.get("default") === "true") { const template = await prisma.formTemplate.findFirst({ where: { organizationId: session.user.orgId, isDefault: true, isActive: true, }, include: { fields: { orderBy: { sortOrder: "asc" } } }, }); return NextResponse.json({ template }); } const templates = await prisma.formTemplate.findMany({ where: { organizationId: session.user.orgId }, orderBy: { createdAt: "desc" }, include: { _count: { select: { fields: true, cards: true } }, }, }); return NextResponse.json({ templates }); } catch (error) { return handleApiError(error); } } function slugify(name: string): string { return name .toLowerCase() .replace(/[^a-z0-9]+/g, "-") .replace(/^-|-$/g, ""); } export async function POST(request: NextRequest) { try { const session = await requireApiAuthWithOrg(); const body = await request.json(); const { name, description, duplicateFrom } = body as { name?: string; description?: string; duplicateFrom?: string; }; if (!name?.trim()) { return NextResponse.json( { error: "Name is required" }, { status: 400 } ); } const baseSlug = slugify(name); let slug = baseSlug; let suffix = 1; while ( await prisma.formTemplate.findUnique({ where: { organizationId_slug: { organizationId: session.user.orgId!, slug, }, }, }) ) { slug = `${baseSlug}-${suffix++}`; } let fieldsToCreate: Prisma.FormFieldCreateWithoutFormTemplateInput[] = []; if (duplicateFrom) { const source = await prisma.formTemplate.findFirst({ where: { id: duplicateFrom, organizationId: session.user.orgId }, include: { fields: { orderBy: { sortOrder: "asc" } } }, }); if (!source) { return NextResponse.json( { error: "Source template not found" }, { status: 404 } ); } fieldsToCreate = source.fields.map((f) => ({ key: f.key, label: f.label, type: f.type, section: f.section, required: f.required, removable: f.removable, isCore: f.isCore, sortOrder: f.sortOrder, options: (f.options ?? Prisma.JsonNull) as Prisma.InputJsonValue, placeholder: f.placeholder, helpText: f.helpText, validation: (f.validation ?? Prisma.JsonNull) as Prisma.InputJsonValue, visibleOnCard: f.visibleOnCard, visibleOnSurvey: f.visibleOnSurvey, })); } const template = await prisma.formTemplate.create({ data: { organizationId: session.user.orgId!, name: name.trim(), slug, description: description?.trim() || null, isDefault: false, isActive: true, ...(fieldsToCreate.length > 0 && { fields: { create: fieldsToCreate }, }), }, include: { fields: { orderBy: { sortOrder: "asc" } }, _count: { select: { cards: true } }, }, }); return NextResponse.json(template, { status: 201 }); } catch (error) { return handleApiError(error); } }