fix(housekeeping): address task 14 review round 2

This commit is contained in:
Simo committed 2026-08-30 11:30:17 +02:00
1 parent d09eaa33d6
commit c524b305d7
17 files changed
+614 -130

No files matched your search

+31 -6
View File
@@ -1,8 +1,9 @@
"use server";
import { revalidatePath } from "next/cache";
import { executeLegacyBrandAssetMutation } from "@/features/housekeeping/domains/content/services/mutation-runtime-external";
import { requirePermission } from "@/lib/admin/guard";
import type { ContentMutationSnapshot } from "@/features/housekeeping/domains/content/services/mutations";
import { createCorrelationId } from "@/features/housekeeping/foundation/contracts";
import { requirePermission, type StaffUser } from "@/lib/admin/guard";
import { PERMS } from "@/lib/permissions";
const MAX_SIZE = 2 * 1024 * 1024;
@@ -15,10 +16,34 @@ const ALLOWED = [
"image/svg+xml",
];
async function executeAuditedFaviconMutation(
staff: StaffUser,
operation: "favicon.save" | "favicon.delete",
input: unknown,
): Promise<ContentMutationSnapshot> {
const [
{ contentProductionMutationAdapter },
{ getHousekeepingCapabilityContext },
] = await Promise.all([
import(
"@/features/housekeeping/domains/content/services/mutations-production"
),
import("@/features/housekeeping/foundation/server-capability-context"),
]);
const capability = await getHousekeepingCapabilityContext();
if (capability.actor.id !== staff.id)
throw new Error("Authenticated staff changed during favicon mutation");
return contentProductionMutationAdapter.execute(operation, input, {
capability,
correlationId: createCorrelationId(),
legacy: true,
});
}
export async function saveFavicon(
formData: FormData,
): Promise<{ success: boolean; url?: string; error?: string }> {
await requirePermission(PERMS.SETTINGS_VIEW);
const staff = await requirePermission(PERMS.SETTINGS_VIEW);
try {
const file = formData.get("file") as File | null;
if (!file || file.size === 0)
@@ -30,7 +55,7 @@ export async function saveFavicon(
success: false,
error: "Invalid file type. Allowed: PNG, JPEG, GIF, WebP, ICO, SVG",
};
const result = await executeLegacyBrandAssetMutation("favicon.save", {
const result = await executeAuditedFaviconMutation(staff, "favicon.save", {
file,
});
siteRevalidate();
@@ -52,9 +77,9 @@ export async function deleteFavicon(): Promise<{
success: boolean;
error?: string;
}> {
await requirePermission(PERMS.SETTINGS_VIEW);
const staff = await requirePermission(PERMS.SETTINGS_VIEW);
try {
await executeLegacyBrandAssetMutation("favicon.delete", {});
await executeAuditedFaviconMutation(staff, "favicon.delete", {});
siteRevalidate();
return { success: true };
} catch (error) {