'use server' import { z } from 'zod' import { requireUser } from '@/lib/auth/current' import { AccessError } from '@/lib/errors' import { requestExport, runExport, type ExportTarget, } from '@/lib/export/service' import { de } from '@/lib/i18n/de' export type ExportState = { jobId?: string; status?: string; error?: string } function toMessage(error: unknown): string { if (error instanceof AccessError) { return de.actionErrors[error.code] ?? de.actionErrors.default! } console.error('[export] unerwartet', error) return de.actionErrors.default! } const requestSchema = z.union([ z.object({ kind: z.literal('CASE'), caseNumber: z.string().min(1) }), z.object({ kind: z.literal('DOCUMENT'), documentNumber: z.string().min(1) }), z.object({ kind: z.literal('PERSONNEL'), personnelFileId: z.string().min(1), // Gedeckelt wird im Dienst auf die Stufe des Abrufers. Hier steht nur die // Form: eine Zahl im gültigen Bereich, nicht irgendein Text. maxLevel: z.coerce.number().int().min(0).max(5), }), z.object({ kind: z.literal('DEPARTMENT'), departmentKey: z.string().min(1), maxLevel: z.coerce.number().int().min(0).max(5), }), ]) /** * Export anfordern. * * Der Auftrag läuft im Hintergrund weiter, nachdem die Antwort raus ist - das * Rendern dauert, und niemand soll auf einen Fortschrittsbalken starren, der * auf Playwright wartet. Siehe docs/09-performance-und-ux.md. */ export async function requestExportAction( _prev: ExportState | null, formData: FormData, ): Promise { const user = await requireUser() const parsed = requestSchema.safeParse(Object.fromEntries(formData)) if (!parsed.success) return { error: de.actionErrors.default! } try { const auftrag = await requestExport(user.permissions, parsed.data as ExportTarget) if (auftrag.status === 'QUEUED') void runExport(auftrag.jobId) return { jobId: auftrag.jobId, status: auftrag.status } } catch (error) { return { error: toMessage(error) } } }