"use server"; import { revalidatePath } from "next/cache"; import { contentMutationService, createContentMutationInvocation, } from "@/features/housekeeping/domains/content/services/mutations"; import { createCorrelationId } from "@/features/housekeeping/foundation/contracts"; import { requirePermission } from "@/lib/admin/guard"; import { PERMS } from "@/lib/permissions"; const MAX_SIZE = 5 * 1024 * 1024; const ALLOWED = ["image/png", "image/jpeg", "image/gif", "image/webp"]; function mediaFile(formData: FormData): File | null { const value = formData.get("file"); return value && typeof value === "object" ? (value as File) : null; } function validateMediaFile(file: File | null): string | null { if (!file || file.size === 0) return "No file provided"; if (file.size > MAX_SIZE) return "File too large (max 5MB)"; if (!ALLOWED.includes(file.type)) return "Invalid file type. Allowed: PNG, JPEG, GIF, WebP"; return null; } export async function uploadMedia( formData: FormData, ): Promise<{ ok: boolean; error?: string }> { const staff = await requirePermission(PERMS.PAGES_EDIT); const file = mediaFile(formData); const error = validateMediaFile(file); if (error) return { ok: false, error }; const result = await contentMutationService.execute( createContentMutationInvocation(staff, createCorrelationId()), "media.upload", { file }, ); if (!result.ok) throw new Error("Media upload failed"); revalidatePath("/api/media"); revalidatePath("/ase/content/media/library"); return { ok: true }; } export async function deleteMedia(name: string): Promise { const staff = await requirePermission(PERMS.PAGES_EDIT); await contentMutationService.execute( createContentMutationInvocation(staff, createCorrelationId()), "media.delete", { filename: name }, ); revalidatePath("/api/media"); revalidatePath("/ase/content/media/library"); } export async function uploadMediaAndReturn( formData: FormData, ): Promise { const staff = await requirePermission(PERMS.PAGES_EDIT); const file = mediaFile(formData); if (validateMediaFile(file)) return ""; const result = await contentMutationService.execute( createContentMutationInvocation(staff, createCorrelationId()), "media.upload", { file }, ); if (!result.ok) return ""; revalidatePath("/api/media"); revalidatePath("/ase/content/media/library"); return typeof result.data.output?.url === "string" ? result.data.output.url : ""; }