68 lines
2.3 KiB
TypeScript
68 lines
2.3 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { auth } from "@/auth";
|
|
import { db } from "@/lib/db";
|
|
import { uploadToHetzner } from "@/lib/storage";
|
|
|
|
function canManage(role: string) {
|
|
return ["ADMIN", "PRODUCER", "SUPERVISOR"].includes(role);
|
|
}
|
|
|
|
// GET /api/sketch-templates — list all templates (any authenticated user)
|
|
export async function GET() {
|
|
const session = await auth();
|
|
if (!session?.user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
|
|
const templates = await db.sketchTemplate.findMany({
|
|
orderBy: { sortOrder: "asc" },
|
|
});
|
|
|
|
return NextResponse.json({
|
|
templates: templates.map((t) => ({
|
|
...t,
|
|
fileSize: t.fileSize != null ? Number(t.fileSize) : null,
|
|
})),
|
|
});
|
|
}
|
|
|
|
// POST /api/sketch-templates — upload + create a new template
|
|
export async function POST(req: NextRequest) {
|
|
const session = await auth();
|
|
if (!session?.user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
if (!canManage(session.user.role))
|
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
|
|
|
const formData = await req.formData();
|
|
const file = formData.get("file") as File | null;
|
|
const name = ((formData.get("name") as string) || "").trim();
|
|
|
|
if (!file) return NextResponse.json({ error: "No file provided" }, { status: 400 });
|
|
if (!file.type.startsWith("image/"))
|
|
return NextResponse.json({ error: "Only image files accepted" }, { status: 400 });
|
|
|
|
const maxSize = 20 * 1024 * 1024; // 20 MB
|
|
if (file.size > maxSize)
|
|
return NextResponse.json({ error: "File too large (max 20 MB)" }, { status: 413 });
|
|
|
|
const buffer = Buffer.from(await file.arrayBuffer());
|
|
const { key: tmplKey } = await uploadToHetzner(buffer, file.name, file.type, "image");
|
|
const uploaded = { url: `/api/files/${tmplKey}`, key: tmplKey };
|
|
|
|
const maxOrder = await db.sketchTemplate.aggregate({ _max: { sortOrder: true } });
|
|
const sortOrder = (maxOrder._max.sortOrder ?? -1) + 1;
|
|
|
|
const template = await db.sketchTemplate.create({
|
|
data: {
|
|
name: name || file.name.replace(/\.[^.]+$/, ""),
|
|
fileUrl: uploaded.url,
|
|
fileKey: uploaded.key,
|
|
fileName: file.name,
|
|
fileSize: BigInt(file.size),
|
|
sortOrder,
|
|
},
|
|
});
|
|
|
|
return NextResponse.json({
|
|
template: { ...template, fileSize: Number(template.fileSize) },
|
|
});
|
|
}
|