feat(WEB): 리스트 페이지 권한 시스템 통합 및 중복 권한 로직 제거
- PermissionContext 기능 확장 (권한 조회 액션 추가) - usePermission 훅 개선 - 회계 모듈 권한 통합: 매입/매출/입금/지출/채권/거래처/어음/일보/부실채권 - 인사 모듈 권한 통합: 근태/카드/급여 관리 - 전자결재 권한 통합: 기안함/결재함 - 게시판/품목/단가/팝업/구독 리스트 권한 적용 - UniversalListPage 권한 연동 - 각 컴포넌트 중복 권한 체크 코드 제거 (-828줄) - 권한 검증 QA 체크리스트 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import { createContext, useContext, useEffect, useState, useCallback } from 'react';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { getRolePermissionMatrix } from '@/lib/permissions/actions';
|
||||
import { getRolePermissionMatrix, getPermissionMenuUrlMap } from '@/lib/permissions/actions';
|
||||
import { buildMenuIdToUrlMap, convertMatrixToPermissionMap, findMatchingUrl, mergePermissionMaps } from '@/lib/permissions/utils';
|
||||
import type { PermissionMap, PermissionAction } from '@/lib/permissions/types';
|
||||
import { AccessDenied } from '@/components/common/AccessDenied';
|
||||
@@ -37,16 +37,31 @@ export function PermissionProvider({ children }: { children: React.ReactNode })
|
||||
const { roleIds, menuIdToUrl } = userData;
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const results = await Promise.all(
|
||||
roleIds.map(id => getRolePermissionMatrix(id))
|
||||
);
|
||||
// 사이드바 메뉴에 없는 권한 메뉴의 URL 매핑 보완
|
||||
// (기준정보 관리, 공정관리 등 사이드바 미등록 메뉴 대응)
|
||||
const [permMenuUrlMap, ...results] = await Promise.all([
|
||||
getPermissionMenuUrlMap(),
|
||||
...roleIds.map(id => getRolePermissionMatrix(id)),
|
||||
]);
|
||||
|
||||
// 권한 메뉴 URL을 베이스로, 사이드바 메뉴 URL로 덮어쓰기 (사이드바 우선)
|
||||
const mergedMenuIdToUrl = { ...permMenuUrlMap, ...menuIdToUrl };
|
||||
|
||||
const maps = results
|
||||
.filter(r => r.success && r.data?.permissions)
|
||||
.map(r => convertMatrixToPermissionMap(r.data.permissions, menuIdToUrl));
|
||||
.map(r => convertMatrixToPermissionMap(r.data.permissions, mergedMenuIdToUrl));
|
||||
|
||||
if (maps.length > 0) {
|
||||
const merged = mergePermissionMaps(maps);
|
||||
|
||||
// 권한 메뉴에 등록되어 있지만 매트릭스 응답에 없는 메뉴 처리
|
||||
// (모든 권한 OFF → API가 해당 menuId를 생략 → "all denied"로 보완)
|
||||
for (const [, url] of Object.entries(permMenuUrlMap)) {
|
||||
if (url && !merged[url]) {
|
||||
merged[url] = { view: false, create: false, update: false, delete: false, approve: false, export: false };
|
||||
}
|
||||
}
|
||||
|
||||
setPermissionMap(merged);
|
||||
} else {
|
||||
setPermissionMap(null);
|
||||
@@ -83,7 +98,7 @@ export function PermissionProvider({ children }: { children: React.ReactNode })
|
||||
const BYPASS_PATHS = ['/settings/permissions'];
|
||||
|
||||
function isGateBypassed(pathname: string): boolean {
|
||||
const pathWithoutLocale = pathname.replace(/^\/[a-z]{2}(\/|$)/, '/');
|
||||
const pathWithoutLocale = pathname.replace(/^\/(ko|en|ja)(\/|$)/, '/');
|
||||
return BYPASS_PATHS.some(bp => pathWithoutLocale.startsWith(bp));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user