import { NextResponse } from 'next/server' import { erfordereZugang, ZugriffVerweigert } from '@/lib/auth/sitzung' import { serienlaufDurchfuehren } from '@/lib/vertraege/serienlauf' import { tagAusText } from '@/lib/finanzen/datum' /** * Fuehrt die Serienabfrage durch und liefert das ZIP. * * POST wie bei den anderen Downloads: Die Auswahl kommt mit, und der Lauf * hat Nebenwirkungen (Dokumente, Fristen, Anfragedatum) - ein GET, das * schreibt, waere eine Falle fuer jeden Vorabruf durch den Browser. * * Die Nebenwirkungen passieren VOR der Auslieferung. Faellt danach noch * etwas beim Herunterladen aus, sind Akte und Fristen trotzdem korrekt - * und die Schreiben liegen als PDF ohnehin in der Akte. */ export const dynamic = 'force-dynamic' export async function POST(anfrage: Request): Promise { let formular: FormData try { formular = await anfrage.formData() } catch { return NextResponse.json({ fehler: 'Ungültige Anfrage.' }, { status: 400 }) } const betreuteId = String(formular.get('betreuteId') ?? '') const stichtagRoh = String(formular.get('stichtag') ?? '').trim() const vertragIds = formular .getAll('vertragId') .map((wert) => String(wert).trim()) .filter(Boolean) if (!betreuteId || vertragIds.length === 0) { return NextResponse.json({ fehler: 'Es ist kein Vertrag ausgewählt.' }, { status: 400 }) } // Obergrenze als Schutz vor Unsinn - real sind es fuenf bis zehn. if (vertragIds.length > 100) { return NextResponse.json({ fehler: 'Zu viele Verträge auf einmal.' }, { status: 400 }) } const stichtag = tagAusText(stichtagRoh) if (!stichtag) { return NextResponse.json({ fehler: 'Bitte einen gültigen Stichtag angeben.' }, { status: 400 }) } let benutzer try { const zugang = await erfordereZugang(betreuteId, 'VERTRAEGE', 'schreiben') benutzer = zugang.benutzer } catch (ausnahme) { if (ausnahme instanceof ZugriffVerweigert) { return NextResponse.json({ fehler: ausnahme.message }, { status: 403 }) } throw ausnahme } const ergebnis = await serienlaufDurchfuehren({ betreuteId, vertragIds, stichtag, benutzer: { id: benutzer.id, name: benutzer.name, email: benutzer.email }, }) return new NextResponse(new Uint8Array(ergebnis.zip), { headers: { 'Content-Type': 'application/zip', 'Content-Disposition': `attachment; filename="${ergebnis.dateiname}"`, 'Content-Length': String(ergebnis.zip.length), 'Cache-Control': 'no-store, must-revalidate', }, }) }