Revert "Merge pull request 'Complete Housekeeping migration and /ase cutover' (#52) from codex/housekeeping-complete into main"
CI / check (push) Successful in 27s
CI / release (push) Skipped
CI / deploy (push) Successful in 43s

This reverts commit 488b6e57c4, reversing
changes made to b506b4499a.
This commit is contained in:
Simo committed 2026-08-30 21:31:34 +02:00
1 parent 488b6e57c4
commit b1ddda66ff
802 files changed
+61370 -76659

No files matched your search

+59 -50
View File
@@ -1,74 +1,83 @@
"use server";
import { mkdir, writeFile } from "node:fs/promises";
import path from "node:path";
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 { MEDIA_ROOT, resolveMediaPath } from "@/lib/media-storage";
import { PERMS } from "@/lib/permissions";
const MAX_SIZE = 5 * 1024 * 1024;
const MAX_SIZE = 5 * 1024 * 1024; // 5MB
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");
await requirePermission(PERMS.PAGES_EDIT);
const file = formData.get("file") as File | null;
if (!file || file.size === 0) return { ok: false, error: "No file provided" };
if (file.size > MAX_SIZE)
return { ok: false, error: "File too large (max 5MB)" };
if (!ALLOWED.includes(file.type))
return {
ok: false,
error: "Invalid file type. Allowed: PNG, JPEG, GIF, WebP",
};
const baseDir = MEDIA_ROOT;
// eslint-disable-next-line security/detect-non-literal-fs-filename
await mkdir(baseDir, { recursive: true });
const ext = file.name.split(".").pop() ?? "png";
const name = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}.${ext}`;
const bytes = await file.arrayBuffer();
const filePath = resolveMediaPath(name);
if (!filePath.startsWith(baseDir + path.sep)) throw new Error("Invalid path");
// eslint-disable-next-line security/detect-non-literal-fs-filename
await writeFile(filePath, Buffer.from(bytes));
revalidatePath("/api/media");
revalidatePath("/ase/content/media/library");
revalidatePath("/admin/media");
return { ok: true };
}
export async function deleteMedia(name: string): Promise<void> {
const staff = await requirePermission(PERMS.PAGES_EDIT);
await contentMutationService.execute(
createContentMutationInvocation(staff, createCorrelationId()),
"media.delete",
{ filename: name },
);
await requirePermission(PERMS.PAGES_EDIT);
const { unlink } = await import("node:fs/promises");
const baseDir = MEDIA_ROOT;
const filePath = resolveMediaPath(name);
if (!filePath.startsWith(baseDir + path.sep)) return;
try {
await unlink(filePath);
} catch {
// File may not exist
}
revalidatePath("/api/media");
revalidatePath("/ase/content/media/library");
revalidatePath("/admin/media");
}
export async function uploadMediaAndReturn(
formData: FormData,
): Promise<string> {
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 "";
await requirePermission(PERMS.PAGES_EDIT);
const file = formData.get("file") as File | null;
if (!file || file.size === 0) return "";
if (file.size > MAX_SIZE) return "";
if (!ALLOWED.includes(file.type)) return "";
const baseDir = MEDIA_ROOT;
// eslint-disable-next-line security/detect-non-literal-fs-filename
await mkdir(baseDir, { recursive: true });
const ext = file.name.split(".").pop() ?? "png";
const name = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}.${ext}`;
const bytes = await file.arrayBuffer();
const filePath = resolveMediaPath(name);
if (!filePath.startsWith(baseDir + path.sep)) return "";
// eslint-disable-next-line security/detect-non-literal-fs-filename
await writeFile(filePath, Buffer.from(bytes));
revalidatePath("/api/media");
revalidatePath("/ase/content/media/library");
return typeof result.data.output?.url === "string"
? result.data.output.url
: "";
revalidatePath("/admin/media");
return `/api/media/${name}`;
}