import { NextResponse } from "next/server"; import { canDocumentExpense } from "@/lib/domain"; import { uploadExpenseProofToDrive } from "@/lib/google-drive"; import prisma from "@/lib/prisma"; import { getCurrentViewer } from "@/lib/session"; const ACCEPTED_MIME_TYPES = new Set(["application/pdf", "image/jpeg", "image/png", "image/webp", "image/heic", "image/heif"]); const MAX_FILE_SIZE = 12 * 1024 * 1024; type Context = { params: Promise<{ id: string; }>; }; export async function POST(request: Request, { params }: Context) { const { id } = await params; const viewer = await getCurrentViewer(); if (!viewer) { return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); } const expense = await prisma.expense.findUnique({ where: { id } }); if (!expense) { return NextResponse.json({ error: "Ausgabe nicht gefunden." }, { status: 404 }); } if (expense.creatorId !== viewer.id && !canDocumentExpense(viewer.role)) { return NextResponse.json({ error: "Du darfst fuer diese Ausgabe keinen Beleg hochladen." }, { status: 403 }); } const formData = await request.formData().catch(() => null); const file = formData?.get("file"); if (!(file instanceof File)) { return NextResponse.json({ error: "Bitte einen Beleg als Bild oder PDF auswaehlen." }, { status: 400 }); } if (!ACCEPTED_MIME_TYPES.has(file.type)) { return NextResponse.json({ error: "Nur Bilder und PDFs sind als Beleg erlaubt." }, { status: 400 }); } if (file.size > MAX_FILE_SIZE) { return NextResponse.json({ error: "Der Beleg darf maximal 12 MB gross sein." }, { status: 400 }); } const proofUrl = await uploadExpenseProofToDrive({ title: expense.title, fileName: file.name, mimeType: file.type, buffer: Buffer.from(await file.arrayBuffer()) }); const updatedExpense = await prisma.expense.update({ where: { id: expense.id }, data: { proofUrl } }); return NextResponse.json({ proofUrl, expense: updatedExpense }); }