'use server' import { revalidatePath } from 'next/cache' import { z } from 'zod' import { requireUser } from '@/lib/auth/current' import { AccessError } from '@/lib/errors' import { releaseAttachment, restoreAttachment, retractAttachment, } from '@/lib/files/service' import { de } from '@/lib/i18n/de' export type ActionResult = { ok: true } | { ok: false; error: string } const schema = z.object({ id: z.string().min(1) }) /** * Freigabe einer Datei, deren Prüfung nicht abgeschlossen werden konnte. * Nur mit Recht `admin`, geprüft im Dienst - nicht hier. */ export async function releaseAttachmentAction(input: unknown): Promise { const user = await requireUser() const parsed = schema.safeParse(input) if (!parsed.success) return { ok: false, error: de.actionErrors.default! } try { await releaseAttachment(user.permissions, parsed.data.id) revalidatePath('/faelle') return { ok: true } } catch (error) { if (error instanceof AccessError) { return { ok: false, error: de.attachment.errors[error.code] ?? de.actionErrors[error.code] ?? de.actionErrors.default!, } } console.error('[dateien] Freigabe fehlgeschlagen', error) return { ok: false, error: de.actionErrors.default! } } } function zuMeldung(error: unknown, stelle: string): ActionResult { if (error instanceof AccessError) { return { ok: false, error: de.attachment.errors[error.code] ?? de.actionErrors[error.code] ?? de.actionErrors.default!, } } console.error(`[dateien] ${stelle} fehlgeschlagen`, error) return { ok: false, error: de.actionErrors.default! } } const ruecknahmeSchema = z.object({ id: z.string().min(1), // Die Mindestlänge steht auch im Dienst und als Bedingung in der Datenbank. // Dreifach, weil eine Rücknahme ohne Grund nur ein Verschwinden mit // Zusatzschritt wäre. reason: z.string().trim().min(10).max(500), }) /** Anhang zurückziehen. Kein Löschen - der Grabstein bleibt stehen. */ export async function retractAttachmentAction(input: unknown): Promise { const user = await requireUser() const parsed = ruecknahmeSchema.safeParse(input) if (!parsed.success) { return { ok: false, error: de.actionErrors['reason-required'] ?? de.actionErrors.default! } } try { await retractAttachment(user.permissions, parsed.data.id, parsed.data.reason) revalidatePath('/faelle') revalidatePath('/personalakten') revalidatePath('/dokumente') return { ok: true } } catch (error) { return zuMeldung(error, 'retract') } } /** Rücknahme aufheben. Steht ebenfalls im Protokoll. */ export async function restoreAttachmentAction(input: unknown): Promise { const user = await requireUser() const parsed = schema.safeParse(input) if (!parsed.success) return { ok: false, error: de.actionErrors.default! } try { await restoreAttachment(user.permissions, parsed.data.id) revalidatePath('/faelle') revalidatePath('/personalakten') revalidatePath('/dokumente') return { ok: true } } catch (error) { return zuMeldung(error, 'restore') } }