// app/actions/permission-settings-actions.ts "use server"; import db from "@/db/db"; import { eq, and, inArray, sql } from "drizzle-orm"; import { permissions, menuAssignments, menuRequiredPermissions } from "@/db/schema"; import { getServerSession } from "next-auth/next" import { authOptions } from "@/app/api/auth/[...nextauth]/route" import { checkUserPermission } from "./service"; // 모든 권한 조회 export async function getAllPermissions() { return await db.select().from(permissions).orderBy(permissions.resource, permissions.action); } // 권한 카테고리 조회 export async function getPermissionCategories() { const result = await db .select({ resource: permissions.resource, count: sql`count(*)`.mapWith(Number), }) .from(permissions) .groupBy(permissions.resource) .orderBy(permissions.resource); return result; } // 권한 생성 export async function createPermission(data: { permissionKey: string; name: string; description?: string; permissionType: string; resource: string; action: string; scope: string; menuPath?: string; uiElement?: string; isActive: boolean; }) { const session = await getServerSession(authOptions) if (!session?.user?.id) { throw new Error("인증이 필요합니다.") } const currentUserId = Number(session.user.id) if (!await checkUserPermission(currentUserId, "admin.permissions.manage")) { throw new Error("권한 관리 권한이 없습니다."); } // 중복 체크 const existing = await db.select() .from(permissions) .where(eq(permissions.permissionKey, data.permissionKey)) .limit(1); if (existing.length > 0) { throw new Error("이미 존재하는 권한 키입니다."); } const [created] = await db.insert(permissions).values({ ...data, isSystem: false, }).returning(); return created; } // 권한 수정 export async function updatePermission(id: number, data: any) { const session = await getServerSession(authOptions) if (!session?.user?.id) { throw new Error("인증이 필요합니다.") } const currentUserId = Number(session.user.id) if (!await checkUserPermission(currentUserId, "admin.permissions.manage")) { throw new Error("권한 관리 권한이 없습니다."); } const [updated] = await db.update(permissions) .set({ ...data, updatedAt: new Date(), }) .where(eq(permissions.id, id)) .returning(); return updated; } // 권한 삭제 export async function deletePermission(id: number) { const session = await getServerSession(authOptions) if (!session?.user?.id) { throw new Error("인증이 필요합니다.") } const currentUserId = Number(session.user.id) if (!await checkUserPermission(currentUserId, "admin.permissions.manage")) { throw new Error("권한 관리 권한이 없습니다."); } await db.delete(permissions).where(eq(permissions.id, id)); } // 메뉴 권한 분석 export async function analyzeMenuPermissions() { const menus = await db.select().from(menuAssignments); const analysis = await Promise.all( menus.map(async (menu) => { // 기존 권한 조회 const existing = await db .select({ id: permissions.id, permissionKey: permissions.permissionKey, name: permissions.name, }) .from(menuRequiredPermissions) .innerJoin(permissions, eq(permissions.id, menuRequiredPermissions.permissionId)) .where(eq(menuRequiredPermissions.menuPath, menu.menuPath)); // 제안할 권한 생성 const suggestedPermissions = []; const resourceName = menu.menuPath.split('/').pop() || 'unknown'; // 기본 메뉴 접근 권한 suggestedPermissions.push({ permissionKey: `${resourceName}.menu_access`, name: `${menu.menuTitle} 접근`, permissionType: "menu_access", action: "access", scope: "assigned", }); // CRUD 권한 제안 const actions = [ { action: "view", name: "조회", type: "data_read" }, { action: "create", name: "생성", type: "data_write" }, { action: "update", name: "수정", type: "data_write" }, { action: "delete", name: "삭제", type: "data_delete" }, ]; actions.forEach(({ action, name, type }) => { suggestedPermissions.push({ permissionKey: `${resourceName}.${action}`, name: `${menu.menuTitle} ${name}`, permissionType: type, action, scope: "assigned", }); }); return { menuPath: menu.menuPath, menuTitle: menu.menuTitle, domain: menu.domain, existingPermissions: existing, suggestedPermissions: suggestedPermissions.filter( sp => !existing.some(ep => ep.permissionKey === sp.permissionKey) ), }; }) ); return analysis; } // 메뉴 기반 권한 생성 export async function generateMenuPermissions( permissionsToCreate: Array<{ permissionKey: string; name: string; permissionType: string; action: string; scope: string; menuPath: string; }> ) { const session = await getServerSession(authOptions) if (!session?.user?.id) { throw new Error("인증이 필요합니다.") } const currentUserId = Number(session.user.id) if (!await checkUserPermission(currentUserId, "admin.permissions.manage")) { throw new Error("권한 관리 권한이 없습니다."); } let created = 0; let skipped = 0; await db.transaction(async (tx) => { for (const perm of permissionsToCreate) { // 중복 체크 const existing = await tx.select() .from(permissions) .where(eq(permissions.permissionKey, perm.permissionKey)) .limit(1); if (existing.length === 0) { const resource = perm.menuPath.split('/').pop() || 'unknown'; await tx.insert(permissions).values({ permissionKey: perm.permissionKey, name: perm.name, permissionType: perm.permissionType, resource, action: perm.action, scope: perm.scope, menuPath: perm.menuPath, isSystem: false, isActive: true, }); created++; } else { skipped++; } } }); return { created, skipped }; }