"use server"; import { z } from "zod"; import { createPeopleMutationInvocation, peopleMutationService, } from "@/features/housekeeping/domains/people/services/mutations"; import { createCorrelationId } from "@/features/housekeeping/foundation/contracts"; import { PERMS } from "@/lib/permissions"; import { adminAction } from "@/lib/safe-action"; import { ActionError, actionOk } from "@/lib/safe-action-shared"; const templateSchema = z.object({ title: z.string().min(1).max(255), content: z.string().min(1), category: z.string().max(50).optional().default("general"), sortOrder: z.coerce.number().int().min(0).default(0), }); async function execute( staff: { readonly id: number }, input: unknown, ) { const result = await peopleMutationService.execute( createPeopleMutationInvocation(staff, createCorrelationId()), "ticket-template.change", input, ); if (!result.ok) { throw new ActionError( result.error.code === "NOT_FOUND" ? "Template not found" : "Template update failed", ); } return result.data; } export const createTemplate = adminAction( { permission: PERMS.TICKETS_EDIT, schema: templateSchema }, async (ctx) => { const snapshot = await execute(ctx.session.user, { action: "create", ...ctx.data, }); return actionOk({ id: Number(snapshot.after?.id) }); }, ); const updateTemplateInput = templateSchema .partial() .extend({ id: z.coerce.number().int().positive() }); export const updateTemplate = adminAction( { permission: PERMS.TICKETS_EDIT, schema: updateTemplateInput }, async (ctx) => { const { id, ...data } = ctx.data; await execute(ctx.session.user, { action: "update", id, ...data }); return actionOk({ id }); }, ); const deleteTemplateInput = z.object({ id: z.coerce.number().int().positive(), }); export const deleteTemplate = adminAction( { permission: PERMS.TICKETS_EDIT, schema: deleteTemplateInput }, async (ctx) => { await execute(ctx.session.user, { action: "delete", id: ctx.data.id }); return actionOk(); }, );