"use server"; import { revalidatePath } from "next/cache"; import { redirect } from "next/navigation"; import { z } from "zod"; import { contentMutationService, createContentMutationInvocation, } from "@/features/housekeeping/domains/content/services/mutations"; import { createCorrelationId } from "@/features/housekeeping/foundation/contracts"; import { requirePermission } from "@/lib/admin/guard"; import { logger } from "@/lib/logger"; import { PERMS } from "@/lib/permissions"; import { adminAction } from "@/lib/safe-action"; import { ActionError, actionOk } from "@/lib/safe-action-shared"; export async function createAd(formData: FormData): Promise { const staff = await requirePermission(PERMS.PAGES_EDIT); const image = String(formData.get("image") ?? "").normalize("NFC").trim().slice(0, 255); if (!image) return; const result = await contentMutationService.execute( createContentMutationInvocation(staff, createCorrelationId()), "ad.change", { action: "create", image }, ); if (!result.ok) { logger.error("Action failed: createAd", { action: "createAd", error: result.error.messageKey }); revalidatePath("/admin/ads"); return; } redirect("/admin/ads"); } export async function updateAd(formData: FormData): Promise { const staff = await requirePermission(PERMS.PAGES_EDIT); const raw = String(formData.get("id") ?? "").normalize("NFC"); if (!/^\d+$/u.test(raw)) return; const image = String(formData.get("image") ?? "").normalize("NFC").trim().slice(0, 255); if (!image) return; const result = await contentMutationService.execute( createContentMutationInvocation(staff, createCorrelationId()), "ad.change", { action: "update", id: raw, image }, ); if (!result.ok) { logger.error("Action failed: updateAd", { action: "updateAd", id: Number(raw), error: result.error.messageKey }); revalidatePath("/admin/ads/" + raw); return; } redirect("/admin/ads"); } const deleteAdInput = z.object({ id: z.union([z.string(), z.number(), z.bigint()]).transform((value) => BigInt(String(value))), }); export const deleteAd = adminAction( { permission: PERMS.PAGES_EDIT, schema: deleteAdInput }, async (ctx) => { const result = await contentMutationService.execute( { correlationId: String(ctx.requestId), expectedActorId: Number(ctx.session.user.id), legacy: true }, "ad.change", { action: "delete", id: ctx.data.id.toString() }, ); if (!result.ok) throw new ActionError("Advertisement not found"); revalidatePath("/admin/ads"); return actionOk(); }, );