'use server' import { revalidatePath } from 'next/cache' import { redirect } from 'next/navigation' import { z } from 'zod' import { requireUser } from '@/lib/auth/current' import { AccessError } from '@/lib/errors' import { createPersonnelFile, reclassifyPersonnelFile, updatePersonnelFile, } from '@/lib/personnel/service' import { de } from '@/lib/i18n/de' export type ActionResult = { ok: true } | { ok: false; error: string } function toMessage(error: unknown): string { if (error instanceof AccessError) { return de.actionErrors[error.code] ?? de.actionErrors.default! } console.error('[personalakten] unerwartet', error) return de.actionErrors.default! } const kopfdaten = { displayName: z.string().min(2).max(120), serviceNumber: z.string().max(60).optional(), rank: z.string().max(60).optional(), department: z.string().max(60).optional(), status: z.string().max(60).optional(), note: z.string().max(2000).optional(), } const createSchema = z.object({ ...kopfdaten, userId: z.string().max(64).optional(), classification: z.coerce.number().int().min(0).max(5), }) export async function createPersonnelAction( _prev: ActionResult | null, formData: FormData, ): Promise { const user = await requireUser() const parsed = createSchema.safeParse(Object.fromEntries(formData)) if (!parsed.success) return { ok: false, error: de.actionErrors['name-required']! } let id: string try { const created = await createPersonnelFile(user.permissions, parsed.data) id = created.id } catch (error) { return { ok: false, error: toMessage(error) } } // Nach dem Anlegen direkt in die Akte, nicht zurück in die Liste. redirect(`/personalakten/${id}`) } const updateSchema = z.object({ id: z.string().min(1), ...kopfdaten }) export async function updatePersonnelAction( _prev: ActionResult | null, formData: FormData, ): Promise { const user = await requireUser() const parsed = updateSchema.safeParse(Object.fromEntries(formData)) if (!parsed.success) return { ok: false, error: de.actionErrors['name-required']! } try { const { id, ...rest } = parsed.data await updatePersonnelFile(user.permissions, id, rest) revalidatePath(`/personalakten/${id}`) return { ok: true } } catch (error) { return { ok: false, error: toMessage(error) } } } const reclassifySchema = z.object({ id: z.string().min(1), to: z.coerce.number().int().min(0).max(5), reason: z.string().max(2000).optional(), }) export async function reclassifyPersonnelAction(input: unknown): Promise { const user = await requireUser() const parsed = reclassifySchema.safeParse(input) if (!parsed.success) return { ok: false, error: de.actionErrors.default! } try { await reclassifyPersonnelFile( user.permissions, parsed.data.id, parsed.data.to, parsed.data.reason, ) revalidatePath(`/personalakten/${parsed.data.id}`) return { ok: true } } catch (error) { return { ok: false, error: toMessage(error) } } }