feat(admin): guilds console + user sanctions timeline
Deploy / release (push) Skipped
Deploy / deploy (push) Successful in 1m44s

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-07-22 21:19:16 +02:00
1 parent 1e77398a7c
commit a384c9a8bb
10 files changed
+3861 -2991

No files matched your search

+48
View File
@@ -0,0 +1,48 @@
"use server";
import { revalidatePath } from "next/cache";
import { requirePermissionRateLimited } from "@/lib/admin/guard";
import { PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { logStaffActivity } from "@/lib/services/staff-activity";
/** Disband a guild and clean related membership/forum rows. */
export async function disbandGuild(formData: FormData): Promise<void> {
const staff = await requirePermissionRateLimited(PERMS.USERS_EDIT);
const id = Number(formData.get("id"));
if (!(id > 0)) return;
const guild = await prisma.guilds.findUnique({
where: { id },
select: { id: true, name: true, userId: true },
});
if (!guild) return;
await prisma.$transaction(async (tx) => {
const threads = await tx.guildsForumsThreads.findMany({
where: { guildId: id },
select: { id: true },
});
const threadIds = threads.map((t) => t.id);
if (threadIds.length > 0) {
await tx.guildsForumsComments.deleteMany({
where: { threadId: { in: threadIds } },
});
await tx.guildsForumsThreads.deleteMany({ where: { guildId: id } });
}
await tx.guildForumViews.deleteMany({ where: { guildId: id } });
await tx.guildsMembers.deleteMany({ where: { guildId: id } });
await tx.rooms.updateMany({ where: { guildId: id }, data: { guildId: 0 } });
await tx.items.updateMany({ where: { guildId: id }, data: { guildId: 0 } });
await tx.guilds.delete({ where: { id } });
});
await logStaffActivity({
staffId: staff.id,
action: "guild_disband",
description: `Disbanded guild #${id} (${guild.name}), owner #${guild.userId}`,
targetType: "guild",
targetId: id,
});
revalidatePath("/admin/guilds");
}