"use server"; import { revalidatePath } from "next/cache"; import { systemMutationService } from "@/features/housekeeping/domains/system/services/mutations"; import { createHousekeepingCapabilityContext } from "@/features/housekeeping/foundation/capability-context"; import { createCorrelationId } from "@/features/housekeeping/foundation/correlation"; import { requirePermission } from "@/lib/admin/guard"; import { PERMS } from "@/lib/permissions"; // Maintenance mode lives in three CMS-owned website_settings rows (mirrors // AtomCMS's MaintenanceToggle Livewire component): // maintenance_enabled '1' | '0' // maintenance_message free text (HTML allowed, shown on the splash) // min_maintenance_login_rank int as string (min rank that may still log in) // The Laravel login flow reads these via setting() to gate non-staff logins // while maintenance is on, so the website_settings keys are the source of truth. function mutationContext(staff: { id: number; rank: number; username: string; }) { const matches = (slug: string) => slug === PERMS.SETTINGS_EDIT; return { capability: createHousekeepingCapabilityContext(staff, { isSuperAdmin: false, has: matches, hasAny: (...slugs: string[]) => slugs.some(matches), hasAll: (...slugs: string[]) => slugs.every(matches), }), correlationId: createCorrelationId(), }; } export async function saveMaintenance(formData: FormData): Promise { const staff = await requirePermission(PERMS.SETTINGS_EDIT); // Checkbox: present only when ticked. Normalise to the '1'/'0' string the // emulator/Laravel side expects. const enabled = formData.get("enabled") != null ? "1" : "0"; const message = String(formData.get("message") ?? "").normalize("NFC"); // Coerce the rank to a non-negative integer; fall back to AtomCMS's default // of 5 when the field is blank or garbage. const rawRank = String(formData.get("min_rank") ?? "") .normalize("NFC") .trim(); const parsedRank = Number.parseInt(rawRank, 10); const minRank = Number.isFinite(parsedRank) && parsedRank >= 0 ? parsedRank : 5; const result = await systemMutationService.execute( mutationContext(staff), "operations.maintenance.update", { enabled: enabled === "1", message, minimumLoginRank: minRank, }, ); if (!result.ok) throw new Error(result.error.messageKey); revalidatePath("/ase/system/operations/maintenance"); }