summaryrefslogtreecommitdiff
path: root/lib/permissions/permission-settings-actions.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-09-26 09:57:24 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-09-26 09:57:24 +0000
commit8b23b471638a155fd1bfa3a8c853b26d9315b272 (patch)
tree47353e9dd342011cb2f1dcd24b09661707a8421b /lib/permissions/permission-settings-actions.ts
parentd62368d2b68d73da895977e60a18f9b1286b0545 (diff)
(대표님) 권한관리, 문서업로드, rfq첨부, SWP문서룰 등
(최겸) 입찰
Diffstat (limited to 'lib/permissions/permission-settings-actions.ts')
-rw-r--r--lib/permissions/permission-settings-actions.ts229
1 files changed, 229 insertions, 0 deletions
diff --git a/lib/permissions/permission-settings-actions.ts b/lib/permissions/permission-settings-actions.ts
new file mode 100644
index 00000000..5d04a1d3
--- /dev/null
+++ b/lib/permissions/permission-settings-actions.ts
@@ -0,0 +1,229 @@
+// 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<number>`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 };
+} \ No newline at end of file