"use server"; import { eq, inArray } from "drizzle-orm"; import { revalidatePath } from "next/cache"; import { requirePermissionRateLimited } from "@/lib/admin/guard"; import { db, GuildForumViews, Guilds, GuildsForumsComments, GuildsForumsThreads, GuildsMembers, Items, Rooms, } from "@/lib/db"; import { PERMS } from "@/lib/permissions"; import { logStaffActivity } from "@/lib/services/staff-activity"; /** Disband a guild and clean related membership/forum rows. */ export async function disbandGuild(formData: FormData): Promise { const staff = await requirePermissionRateLimited(PERMS.USERS_EDIT); const id = Number(formData.get("id")); if (!(id > 0)) return; const [guild] = await db .select({ id: Guilds.id, name: Guilds.name, userId: Guilds.userId, }) .from(Guilds) .where(eq(Guilds.id, id)) .limit(1); if (!guild) return; await db.transaction(async (tx) => { const threads = await tx .select({ id: GuildsForumsThreads.id }) .from(GuildsForumsThreads) .where(eq(GuildsForumsThreads.guildId, id)); const threadIds = threads.map((t) => t.id); if (threadIds.length > 0) { await tx .delete(GuildsForumsComments) .where(inArray(GuildsForumsComments.threadId, threadIds)); await tx .delete(GuildsForumsThreads) .where(eq(GuildsForumsThreads.guildId, id)); } await tx.delete(GuildForumViews).where(eq(GuildForumViews.guildId, id)); await tx.delete(GuildsMembers).where(eq(GuildsMembers.guildId, id)); await tx.update(Rooms).set({ guildId: 0 }).where(eq(Rooms.guildId, id)); await tx.update(Items).set({ guildId: 0 }).where(eq(Items.guildId, id)); await tx.delete(Guilds).where(eq(Guilds.id, 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"); }