Files
EpicNext-Cms/src/actions/catalog-bc.ts
T
simoleo89andCursor 0e89d03940 Finish fine-grained ACL across remaining admin pages and actions.
Replace leftover requireStaff gates with module PERMS, drop hardcoded room rank thresholds, and expand contract tests so admin mutations cannot regress to dashboard-only checks.

Co-authored-by: Cursor <[email protected]>
2026-07-15 20:15:22 +02:00

137 lines
3.5 KiB
TypeScript

"use server";
import { revalidatePath } from "next/cache";
import { requirePermission } from "@/lib/admin/guard";
import { PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { rcon } from "@/lib/services/rcon";
import { logStaffActivity } from "@/lib/services/staff-activity";
export async function updateBcPage({
id,
...fields
}: { id: number } & Record<string, unknown>) {
const staff = await requirePermission(PERMS.CATALOG_EDIT);
await prisma.catalogPagesBc.update({ where: { id }, data: fields as any });
await rcon.updateCatalog();
await logStaffActivity({
staffId: staff.id,
action: "bc_page_update",
description: `Updated BC catalog page #${id}`,
targetType: "catalog_page_bc",
targetId: id,
});
revalidatePath("/admin/catalog/builder-club");
return { ok: true as const };
}
export async function deleteBcItem({ id }: { id: number }) {
const staff = await requirePermission(PERMS.CATALOG_EDIT);
await prisma.catalogItemsBc.delete({ where: { id } });
await logStaffActivity({
staffId: staff.id,
action: "bc_item_delete",
description: `Deleted BC catalog item #${id}`,
targetType: "catalog_item_bc",
targetId: id,
});
revalidatePath("/admin/catalog/builder-club");
}
export async function updateBcItem({
id,
...data
}: {
id: number;
itemIds?: string;
catalogName?: string;
orderNumber?: number;
extradata?: string;
}) {
const staff = await requirePermission(PERMS.CATALOG_EDIT);
await prisma.catalogItemsBc.update({ where: { id }, data: data as any });
await logStaffActivity({
staffId: staff.id,
action: "bc_item_update",
description: `Updated BC catalog item #${id}`,
targetType: "catalog_item_bc",
targetId: id,
});
revalidatePath("/admin/catalog/builder-club");
}
export async function createBcItem({
pageId,
...data
}: {
pageId: number;
itemIds: string;
catalogName: string;
orderNumber: number;
extradata: string;
}) {
const staff = await requirePermission(PERMS.CATALOG_EDIT);
const created = await prisma.catalogItemsBc.create({
data: { pageId, ...data },
});
await logStaffActivity({
staffId: staff.id,
action: "bc_item_create",
description: `Created BC catalog item #${created.id}`,
targetType: "catalog_item_bc",
targetId: created.id,
});
revalidatePath("/admin/catalog/builder-club");
}
export async function toggleBcPage({
id,
field,
}: {
id: number;
field: "enabled" | "visible";
}) {
await requirePermission(PERMS.CATALOG_EDIT);
const page = await prisma.catalogPagesBc.findUnique({
where: { id },
select: { enabled: true, visible: true },
});
if (!page) return;
await prisma.catalogPagesBc.update({
where: { id },
data: { [field]: page[field] === "1" ? "0" : "1" },
});
revalidatePath("/admin/catalog/builder-club");
}
export async function createBcPage(input: {
caption: string;
parentId: number;
pageLayout: string;
}) {
const staff = await requirePermission(PERMS.CATALOG_EDIT);
const created = await prisma.catalogPagesBc.create({
data: {
caption: input.caption,
parentId: input.parentId,
pageLayout: input.pageLayout,
iconColor: 0,
iconImage: 0,
orderNum: 0,
visible: "1",
enabled: "1",
pageHeadline: "",
pageTeaser: "",
},
});
await logStaffActivity({
staffId: staff.id,
action: "bc_page_create",
description: `Created BC catalog page "${input.caption}"`,
targetType: "catalog_page_bc",
targetId: created.id,
});
revalidatePath("/admin/catalog/builder-club");
return { ok: true as const, data: { id: created.id } };
}