113 lines
3.2 KiB
TypeScript
113 lines
3.2 KiB
TypeScript
|
|
import { NextRequest, NextResponse } from "next/server";
|
||
|
|
import { prisma } from "@/lib/db";
|
||
|
|
import { requireApiAuthWithOrg, handleApiError } from "@/lib/api-auth";
|
||
|
|
|
||
|
|
type RouteContext = { params: Promise<{ id: string }> };
|
||
|
|
|
||
|
|
async function getOwnedTemplate(templateId: string, orgId: string) {
|
||
|
|
const template = await prisma.formTemplate.findUnique({
|
||
|
|
where: { id: templateId },
|
||
|
|
include: {
|
||
|
|
fields: { orderBy: { sortOrder: "asc" } },
|
||
|
|
_count: { select: { cards: true } },
|
||
|
|
},
|
||
|
|
});
|
||
|
|
if (!template || template.organizationId !== orgId) return null;
|
||
|
|
return template;
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function GET(_request: NextRequest, ctx: RouteContext) {
|
||
|
|
try {
|
||
|
|
const session = await requireApiAuthWithOrg();
|
||
|
|
const { id } = await ctx.params;
|
||
|
|
|
||
|
|
const template = await getOwnedTemplate(id, session.user.orgId!);
|
||
|
|
if (!template) {
|
||
|
|
return NextResponse.json(
|
||
|
|
{ error: "Template not found" },
|
||
|
|
{ status: 404 }
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
return NextResponse.json(template);
|
||
|
|
} catch (error) {
|
||
|
|
return handleApiError(error);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function PUT(request: NextRequest, ctx: RouteContext) {
|
||
|
|
try {
|
||
|
|
const session = await requireApiAuthWithOrg();
|
||
|
|
const { id } = await ctx.params;
|
||
|
|
|
||
|
|
const existing = await getOwnedTemplate(id, session.user.orgId!);
|
||
|
|
if (!existing) {
|
||
|
|
return NextResponse.json(
|
||
|
|
{ error: "Template not found" },
|
||
|
|
{ status: 404 }
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
const body = await request.json();
|
||
|
|
const { name, description, isActive, branding, settings } = body as {
|
||
|
|
name?: string;
|
||
|
|
description?: string;
|
||
|
|
isActive?: boolean;
|
||
|
|
branding?: Record<string, unknown>;
|
||
|
|
settings?: Record<string, unknown>;
|
||
|
|
};
|
||
|
|
|
||
|
|
const data: Record<string, unknown> = {};
|
||
|
|
if (name !== undefined) data.name = name.trim();
|
||
|
|
if (description !== undefined) data.description = description?.trim() || null;
|
||
|
|
if (isActive !== undefined) data.isActive = Boolean(isActive);
|
||
|
|
if (branding !== undefined) data.branding = branding;
|
||
|
|
if (settings !== undefined) data.settings = settings;
|
||
|
|
|
||
|
|
const updated = await prisma.formTemplate.update({
|
||
|
|
where: { id },
|
||
|
|
data,
|
||
|
|
include: {
|
||
|
|
fields: { orderBy: { sortOrder: "asc" } },
|
||
|
|
_count: { select: { cards: true } },
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
return NextResponse.json(updated);
|
||
|
|
} catch (error) {
|
||
|
|
return handleApiError(error);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function DELETE(_request: NextRequest, ctx: RouteContext) {
|
||
|
|
try {
|
||
|
|
const session = await requireApiAuthWithOrg();
|
||
|
|
const { id } = await ctx.params;
|
||
|
|
|
||
|
|
const existing = await getOwnedTemplate(id, session.user.orgId!);
|
||
|
|
if (!existing) {
|
||
|
|
return NextResponse.json(
|
||
|
|
{ error: "Template not found" },
|
||
|
|
{ status: 404 }
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (existing._count.cards > 0) {
|
||
|
|
const deactivated = await prisma.formTemplate.update({
|
||
|
|
where: { id },
|
||
|
|
data: { isActive: false },
|
||
|
|
});
|
||
|
|
return NextResponse.json({
|
||
|
|
...deactivated,
|
||
|
|
_deactivated: true,
|
||
|
|
_reason: "Template has associated cards and was deactivated instead of deleted",
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
await prisma.formTemplate.delete({ where: { id } });
|
||
|
|
return NextResponse.json({ deleted: true });
|
||
|
|
} catch (error) {
|
||
|
|
return handleApiError(error);
|
||
|
|
}
|
||
|
|
}
|