'use server'; import { executeServerAction, type ActionResult } from '@/lib/api/execute-server-action'; import { revalidatePath } from 'next/cache'; import type { Role, RoleStats, PermissionMatrix, MenuTreeItem, PaginatedResponse } from './types'; const API_URL = process.env.NEXT_PUBLIC_API_URL; // ========== Role CRUD ========== export async function fetchRoles(params?: { page?: number; size?: number; q?: string; is_hidden?: boolean; }): Promise>> { const searchParams = new URLSearchParams(); if (params?.page) searchParams.set('page', params.page.toString()); if (params?.size) searchParams.set('per_page', params.size.toString()); if (params?.q) searchParams.set('q', params.q); if (params?.is_hidden !== undefined) searchParams.set('is_hidden', params.is_hidden.toString()); const queryString = searchParams.toString(); return executeServerAction>({ url: `${API_URL}/api/v1/roles${queryString ? `?${queryString}` : ''}`, errorMessage: '역할 목록 조회에 실패했습니다.', }); } export async function fetchRole(id: number): Promise> { return executeServerAction({ url: `${API_URL}/api/v1/roles/${id}`, errorMessage: '역할 조회에 실패했습니다.', }); } export async function createRole(data: { name: string; description?: string; is_hidden?: boolean; }): Promise> { const result = await executeServerAction({ url: `${API_URL}/api/v1/roles`, method: 'POST', body: data, errorMessage: '역할 생성에 실패했습니다.', }); if (result.success) revalidatePath('/settings/permissions'); return result; } export async function updateRole(id: number, data: { name?: string; description?: string; is_hidden?: boolean; }): Promise> { const result = await executeServerAction({ url: `${API_URL}/api/v1/roles/${id}`, method: 'PATCH', body: data, errorMessage: '역할 수정에 실패했습니다.', }); if (result.success) { revalidatePath('/settings/permissions'); revalidatePath(`/settings/permissions/${id}`); } return result; } export async function deleteRole(id: number): Promise { const result = await executeServerAction({ url: `${API_URL}/api/v1/roles/${id}`, method: 'DELETE', errorMessage: '역할 삭제에 실패했습니다.', }); if (result.success) revalidatePath('/settings/permissions'); return result; } export async function fetchRoleStats(): Promise> { return executeServerAction({ url: `${API_URL}/api/v1/roles/stats`, errorMessage: '역할 통계 조회에 실패했습니다.', }); } export async function fetchActiveRoles(): Promise> { return executeServerAction({ url: `${API_URL}/api/v1/roles/active`, errorMessage: '활성 역할 목록 조회에 실패했습니다.', }); } // ========== Permission Matrix ========== export async function fetchPermissionMenus(): Promise> { return executeServerAction({ url: `${API_URL}/api/v1/role-permissions/menus`, errorMessage: '메뉴 트리 조회에 실패했습니다.', }); } export async function fetchPermissionMatrix(roleId: number): Promise> { return executeServerAction({ url: `${API_URL}/api/v1/roles/${roleId}/permissions/matrix`, errorMessage: '권한 매트릭스 조회에 실패했습니다.', }); } export async function togglePermission(roleId: number, menuId: number, permissionType: string): Promise> { const result = await executeServerAction<{ granted: boolean; propagated_to: number[] }>({ url: `${API_URL}/api/v1/roles/${roleId}/permissions/toggle`, method: 'POST', body: { menu_id: menuId, permission_type: permissionType }, errorMessage: '권한 토글에 실패했습니다.', }); if (result.success) revalidatePath(`/settings/permissions/${roleId}`); return result; } async function rolePermissionAction(roleId: number, action: string, errorMessage: string): Promise> { const result = await executeServerAction<{ count: number }>({ url: `${API_URL}/api/v1/roles/${roleId}/permissions/${action}`, method: 'POST', errorMessage, }); if (result.success) revalidatePath(`/settings/permissions/${roleId}`); return result; } export async function allowAllPermissions(roleId: number): Promise> { return rolePermissionAction(roleId, 'allow-all', '전체 허용에 실패했습니다.'); } export async function denyAllPermissions(roleId: number): Promise> { return rolePermissionAction(roleId, 'deny-all', '전체 거부에 실패했습니다.'); } export async function resetPermissions(roleId: number): Promise> { return rolePermissionAction(roleId, 'reset', '권한 초기화에 실패했습니다.'); }