Files
sam-react-prod/claudedocs/[PLAN-2025-01-20] permission-system-implementation.md
유병철 f6551c7e8b feat(WEB): 전체 페이지 ?mode= URL 네비게이션 패턴 적용
- 등록(?mode=new), 상세(?mode=view), 수정(?mode=edit) URL 패턴 일괄 적용
- 중복 패턴 제거: /edit?mode=edit → ?mode=edit (16개 파일)
- 제목 일관성: {기능} 등록/상세/수정 패턴 적용
- 검수 체크리스트 문서 추가 (79개 페이지)
- UniversalListPage, IntegratedDetailTemplate 공통 컴포넌트 개선

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 12:27:43 +09:00

34 KiB

권한 시스템 구현 계획서

작성일: 2025-01-20 최종 수정: 2026-01-21 상태: 계획 완료 (구현 대기)


📊 전체 페이지 분석 결과 (2026-01-21 추가)

핵심 통계

구분 수량 비고
전체 Protected 페이지 206개 src/app/[locale]/(protected)
템플릿 자동 적용 가능 165개+ 템플릿 2개 수정으로 해결
개별 작업 필요 페이지 41개 수동 권한 적용
Config 파일 46개 menuCode 추가 필요

템플릿 사용 현황

템플릿 사용 컴포넌트 수 적용 방식
UniversalListPage (리스트) 64개 자동 (템플릿 수정)
IntegratedDetailTemplate (상세/폼) 101개+ 자동 (템플릿 수정)
직접 구현 41개 수동 (usePermission 적용)

효율성 분석

✅ 템플릿 2개 수정 = 165개+ 페이지 자동 권한 적용 (80%)
⚠️ 개별 41개 페이지 = 수동 작업 필요 (20%)
🎯 ROI: 템플릿 2개 → 165개 페이지 = 82.5배 효율

📈 공통화/추상화 효율 분석 (2026-01-23 추가)

측정 관점 차이 설명

구분 page.tsx 레벨 컴포넌트 레벨 설명
측정 대상 page.tsx 파일 도메인 컴포넌트 관점 차이
UniversalListPage 4개 페이지 64개 컴포넌트 컴포넌트가 템플릿 사용
IntegratedDetailTemplate 18개 페이지 101개 컴포넌트 컴포넌트가 템플릿 사용
직접 사용률 12.1% 80% 컴포넌트 레벨이 실제 효율

구조:

page.tsx (207개) → 도메인 컴포넌트 (165개+) → 템플릿 (2개)
                   ↑                         ↑
                 여기서 렌더링            여기서 권한 적용

공통화 수준 평가

단계 항목 달성도 상태
Level 1 공통 UI 컴포넌트 (52개) 80% 양호
Level 2 계층 구조 (Atomic Design) 40% 🟡 부분
Level 3 템플릿/레이아웃 30% 🟡 부분
Level 4 Config 기반 구현 25% 🟡 미흡
Level 5 권한 자동화 10% 🔴 미흡

종합 공통화 수준: 약 35-40%

권한 적용 전략 비교

전략 자동 적용 수동 적용 효율
page.tsx 레벨 분석 22개 (10.6%) 185개 (89.4%) 🔴 낮음
컴포넌트 레벨 분석 165개+ (80%) 41개 (20%) 높음

권한 적용 구조도

┌─────────────────────────────────────────────────────┐
│                 전체 207개 페이지                    │
├─────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────┐   │
│  │     템플릿 사용 컴포넌트 경유 (165개+)        │   │
│  │  ┌───────────────┐ ┌───────────────────┐   │   │
│  │  │ UniversalList │ │ IntegratedDetail  │   │   │
│  │  │   Page (64)   │ │   Template (101)  │   │   │
│  │  └───────────────┘ └───────────────────┘   │   │
│  │              ↓                              │   │
│  │      Config에 menuCode 추가                 │   │
│  │              ↓                              │   │
│  │      ✅ 자동 권한 적용 (80%)                 │   │
│  └─────────────────────────────────────────────┘   │
│                                                     │
│  ┌─────────────────────────────────────────────┐   │
│  │      특수 페이지 (41개)                       │   │
│  │  대시보드, 설정, 전자결재, QMS 등             │   │
│  │              ↓                              │   │
│  │      usePermission 훅 직접 적용              │   │
│  │              ↓                              │   │
│  │      ⚠️ 수동 권한 적용 (20%)                 │   │
│  └─────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────┘

최종 결론

항목 수치 비고
공통화 수준 35-40% 잠재력 높음
권한 자동 적용 80% (165개+ 컴포넌트) Config + 템플릿
권한 수동 적용 20% (41개 특수 페이지) usePermission
Config 수정 47개 파일 menuCode 추가
템플릿 수정 2개 파일 권한 체크 로직

권한 시스템은 계획서대로 진행 가능:

  • 템플릿 2개 수정 → 165개+ 컴포넌트 자동 적용
  • 41개 특수 페이지만 개별 작업

0. 확정 사항 (2025-01-21)

항목 결정
백엔드 API 기존 /api/v1/permissions/users/{userId}/menu-matrix 활용
추가 API 필요 불필요
캐싱 전략 로그인 시 1회 로드
권한 반영 시점 재로그인 시 적용
선행 조건 페이지 통합 작업 완료 후 진행

1. 현재 상태 분석

1.1 구현 완료 항목

구분 상태 위치
역할(Role) CRUD /settings/permissions
권한 매트릭스 UI PermissionDetailClient.tsx
권한 타입 정의 types.ts
메뉴 트리 API GET /api/v1/role-permissions/menus
권한 토글 API POST /api/v1/roles/{id}/permissions/toggle

1.2 미구현 항목

구분 필요성 우선순위 비고
현재 사용자 권한 조회 API 필수 🔴 높음 기존 API 활용
PermissionContext/Provider 필수 🔴 높음
usePermission 훅 필수 🔴 높음
PermissionGuard 컴포넌트 필수 🟡 중간
Config에 권한 정보 추가 필수 🟡 중간
AccessDenied 페이지 권장 🟢 낮음

2. 권한 데이터 구조

2.1 권한 타입 (7가지)

type PermissionType = 'view' | 'create' | 'update' | 'delete' | 'approve' | 'export' | 'manage';

const PERMISSION_LABELS: Record<PermissionType, string> = {
  view: '조회',
  create: '생성',
  update: '수정',
  delete: '삭제',
  approve: '승인',
  export: '내보내기',
  manage: '관리',
};

2.2 권한 매트릭스 구조

interface UserPermissions {
  role: {
    id: number;
    name: string;
  };
  permissions: {
    [menuCode: string]: {
      view?: boolean;
      create?: boolean;
      update?: boolean;
      delete?: boolean;
      approve?: boolean;
      export?: boolean;
      manage?: boolean;
    };
  };
}

2.3 메뉴 트리 구조

interface MenuTreeItem {
  id: number;
  name: string;
  code: string;           // 권한 체크 시 사용되는 키
  parent_id: number | null;
  depth: number;
  sort_order: number;
  children?: MenuTreeItem[];
}

3. 구현 계획

Phase 1: 기반 구조 ( 백엔드 준비 완료)

3.1.1 사용할 API

기존 API 활용:

GET /api/v1/permissions/users/{userId}/menu-matrix

Response:
{
  "success": true,
  "data": {
    "actions": ["view", "create", "update", "delete", "approve"],
    "tree": [
      {
        "menu_id": 1,
        "parent_id": null,
        "name": "수주관리",
        "url": "/sales/order-management",
        "type": "system",
        "children": [...],
        "actions": {
          "view": { "permission_id": 123, "state": "allow", "is_allowed": 1 },
          "create": { "permission_id": 124, "state": "allow", "is_allowed": 1 },
          "update": { "permission_id": 125, "state": "deny", "is_allowed": 0 },
          "delete": { "permission_id": 126, "state": "none", "is_allowed": 0 },
          "approve": { "permission_id": 127, "state": "allow", "is_allowed": 1 }
        }
      }
    ]
  }
}

프론트엔드 변환 필요:

  • 트리 구조 → flat 권한 객체로 변환
  • url 기반으로 menuCode 추출 (예: /sales/order-managementorder-management)

3.1.2 파일 구조

src/
├── contexts/
│   └── PermissionContext.tsx    # 권한 Context + Provider
├── hooks/
│   └── usePermission.ts         # 권한 체크 훅
└── lib/
    └── permissions/
        ├── types.ts             # 권한 관련 타입
        └── actions.ts           # 권한 조회 Server Action

3.1.3 PermissionContext 설계

// src/contexts/PermissionContext.tsx

interface PermissionContextType {
  permissions: UserPermissions | null;
  isLoading: boolean;
  error: string | null;
  can: (menuCode: string, action: PermissionType) => boolean;
  canAny: (menuCode: string, actions: PermissionType[]) => boolean;
  canAll: (menuCode: string, actions: PermissionType[]) => boolean;
  refresh: () => Promise<void>;
}

3.1.4 usePermission 훅 설계

// src/hooks/usePermission.ts

interface UsePermissionReturn {
  canView: boolean;
  canCreate: boolean;
  canUpdate: boolean;
  canDelete: boolean;
  canApprove: boolean;
  canExport: boolean;
  canManage: boolean;
  isLoading: boolean;
}

function usePermission(menuCode: string): UsePermissionReturn;

// 사용 예시
const { canView, canCreate, canUpdate, canDelete } = usePermission('order-management');

Phase 2: Config 확장

3.2.1 DetailConfig 타입 확장

// src/components/templates/IntegratedDetailTemplate/types.ts

interface PermissionConfig {
  menuCode: string;              // 메뉴 코드 (API와 매핑)
  requiredAction?: PermissionType; // 페이지 접근에 필요한 최소 권한 (기본: 'view')
}

interface DetailConfig {
  title: string;
  description: string;
  icon: LucideIcon;
  basePath: string;
  fields: FieldConfig[];
  actions: ActionConfig;
  permission?: PermissionConfig;  // 🆕 추가
}

3.2.2 Config 파일 업데이트 예시

수정 전:

export const orderCreateConfig: DetailConfig = {
  title: '수주 등록',
  basePath: '/sales/order-management',
  // ...
};

수정 후:

export const orderCreateConfig: DetailConfig = {
  title: '수주 등록',
  basePath: '/sales/order-management',
  permission: {
    menuCode: 'order-management',
    requiredAction: 'create',
  },
  // ...
};

3.2.3 업데이트 대상 Config 파일 (46개)

카테고리 수량 Config 파일
회계 (Accounting) 8개 badDebtConfig, billConfig, depositDetailConfig, purchaseConfig, salesConfig, vendorConfig, vendorLedgerConfig, withdrawalDetailConfig
건설 (Construction) 15개 biddingConfig, contractConfig, estimateConfig, handoverReportConfig, issueConfig, itemConfig, laborDetailConfig, constructionConfig, orderConfig, partnerConfig, pricingDetailConfig, progressBillingConfig, siteBriefingConfig, siteConfig, structureReviewConfig
고객/클라이언트 2개 clientConfig, clientDetailConfig
고객센터 3개 eventConfig, inquiryConfig, noticeConfig
HR 2개 cardConfig, employeeConfig
자재 2개 receivingConfig, stockStatusConfig
주문 2개 orderConfig, orderSalesConfig
생산 1개 workOrderConfig
프로세스 1개 processConfig
품질 1개 inspectionConfig
견적 2개 quoteConfig, quoteRegistrationConfig
설정 3개 accountConfig, permissionConfig, popupDetailConfig
유통 1개 shipmentConfig
게시판 1개 boardFormConfig
전자결재 1개 documentCreateConfig
기타 1개 importInspectionConfig

Config 파일 전체 경로:

src/components/
├── accounting/
│   ├── BadDebtCollection/badDebtConfig.ts
│   ├── BillManagement/billConfig.ts
│   ├── DepositManagement/depositDetailConfig.ts
│   ├── PurchaseManagement/purchaseConfig.ts
│   ├── SalesManagement/salesConfig.ts
│   ├── VendorLedger/vendorLedgerConfig.ts
│   ├── VendorManagement/vendorConfig.ts
│   └── WithdrawalManagement/withdrawalDetailConfig.ts
├── approval/
│   └── DocumentCreate/documentCreateConfig.ts
├── board/
│   └── BoardForm/boardFormConfig.ts
├── business/construction/
│   ├── bidding/biddingConfig.ts
│   ├── contract/contractConfig.ts
│   ├── estimates/estimateConfig.ts
│   ├── handover-report/handoverReportConfig.ts
│   ├── issue-management/issueConfig.ts
│   ├── item-management/itemConfig.ts
│   ├── labor-management/laborDetailConfig.ts
│   ├── management/constructionConfig.ts
│   ├── order-management/orderConfig.ts
│   ├── partners/partnerConfig.ts
│   ├── pricing-management/pricingDetailConfig.ts
│   ├── progress-billing/progressBillingConfig.ts
│   ├── site-briefings/siteBriefingConfig.ts
│   ├── site-management/siteConfig.ts
│   └── structure-review/structureReviewConfig.ts
├── clients/
│   ├── clientConfig.ts
│   └── clientDetailConfig.ts
├── customer-center/
│   ├── EventManagement/eventConfig.ts
│   ├── InquiryManagement/inquiryConfig.ts
│   └── NoticeManagement/noticeConfig.ts
├── hr/
│   ├── CardManagement/cardConfig.ts
│   └── EmployeeManagement/employeeConfig.ts
├── material/
│   ├── ReceivingManagement/receivingConfig.ts
│   ├── ReceivingManagement/inspectionConfig.ts (importInspectionConfig)
│   └── StockStatus/stockStatusConfig.ts
├── orders/
│   ├── orderConfig.ts
│   └── orderSalesConfig.ts
├── outbound/
│   └── ShipmentManagement/shipmentConfig.ts
├── process-management/
│   └── processConfig.ts
├── production/
│   └── WorkOrders/workOrderConfig.ts
├── quality/
│   └── InspectionManagement/inspectionConfig.ts
├── quotes/
│   ├── quoteConfig.ts
│   └── quoteRegistrationConfig.ts
└── settings/
    ├── AccountManagement/accountConfig.ts
    ├── PermissionManagement/permissionConfig.ts
    └── PopupManagement/popupDetailConfig.ts

Phase 3: 공통 컴포넌트

3.3.1 PermissionGuard 컴포넌트

// src/components/common/PermissionGuard.tsx

interface PermissionGuardProps {
  menuCode: string;
  action: PermissionType;
  fallback?: React.ReactNode;  // 권한 없을 때 대체 UI
  children: React.ReactNode;
}

// 사용 예시
<PermissionGuard menuCode="order-management" action="delete">
  <Button variant="destructive">삭제</Button>
</PermissionGuard>

<PermissionGuard
  menuCode="order-management"
  action="update"
  fallback={<ReadOnlyView />}
>
  <EditForm />
</PermissionGuard>

3.3.2 AccessDenied 페이지

// src/components/common/AccessDenied.tsx

interface AccessDeniedProps {
  title?: string;
  description?: string;
  showBackButton?: boolean;
}

// 기본 메시지: "접근 권한이 없습니다"

3.3.3 파일 구조

src/components/common/
├── PermissionGuard.tsx      # 권한 기반 조건부 렌더링
├── AccessDenied.tsx         # 접근 거부 페이지
└── index.ts                 # export

Phase 4: 페이지별 적용

3.4.1 IntegratedDetailTemplate 수정

// 템플릿 내부에서 자동 권한 체크
function IntegratedDetailTemplate({ config, ...props }) {
  const menuCode = config.permission?.menuCode;
  const { canView, canCreate, canUpdate, canDelete } = usePermission(menuCode || '');

  // 페이지 접근 권한 체크
  if (menuCode && !canView) {
    return <AccessDenied />;
  }

  // 버튼 자동 숨김
  const effectiveActions = {
    ...config.actions,
    showSave: config.actions.showSave && (mode === 'create' ? canCreate : canUpdate),
    showDelete: config.actions.showDelete && canDelete,
  };

  return (
    // ... 기존 렌더링
  );
}

3.4.2 UniversalListPage 수정

// 리스트 템플릿 내부에서 자동 권한 체크
function UniversalListPage({ config, ...props }) {
  const menuCode = config.permission?.menuCode;
  const { canView, canCreate, canUpdate, canDelete } = usePermission(menuCode || '');

  // 페이지 접근 권한 체크
  if (menuCode && !canView) {
    return <AccessDenied />;
  }

  // 버튼 자동 숨김
  const showCreateButton = config.showCreateButton && canCreate;
  const showDeleteButton = config.showDeleteButton && canDelete;
  const showEditAction = canUpdate;

  return (
    // ... 기존 렌더링
  );
}

3.4.3 적용 방식

방식 적용 위치 제어 수준 비율
자동 IntegratedDetailTemplate Config 기반 ~49% (101개)
자동 UniversalListPage Config 기반 ~31% (64개)
수동 개별 컴포넌트 usePermission 훅 ~20% (41개)

3.4.4 개별 작업 필요 페이지 목록 (41개)

우선순위 1 - HIGH (8개)
페이지 경로 복잡도 작업 내용
대시보드 /dashboard 🟡 중간 역할별 위젯 필터링
생산 대시보드 /production/dashboard 🟡 중간 생산 권한 기반 위젯
계정정보 /settings/account-info 🟢 낮음 사용자 정보 접근 권한
출퇴근설정 /settings/attendance-settings 🟢 낮음 관리자 권한 체크
휴가정책 /settings/leave-policy 🟢 낮음 HR 권한 체크
직급관리 /settings/ranks 🟢 낮음 관리자 권한 체크
직책관리 /settings/titles 🟢 낮음 관리자 권한 체크
근무일정 /settings/work-schedule 🟢 낮음 관리자 권한 체크
우선순위 2 - MEDIUM (15개)
페이지 경로 복잡도 작업 내용
기안작성 /approval/draft/new 🟡 중간 결재 권한
결재함 /approval/inbox 🟡 중간 결재자 권한
참조함 /approval/reference 🟢 낮음 참조 권한
게시글 작성 /board/create 🟢 낮음 게시판 권한
게시글 상세 /boards/[boardCode]/[postId] 🟡 중간 작성자/관리자 권한
부서관리 /hr/department-management 🟡 중간 HR 권한 (트리 구조)
품목기준관리 /master-data/item-master-data-management 🟢 낮음 데이터 조회 권한
공정관리 /master-data/process-management 🟢 낮음 데이터 조회 권한
FAQ /customer-center/faq 🟢 낮음 조회 권한 (아코디언)
1:1 문의 /customer-center/qna 🟢 낮음 문의 권한
회사정보 /company-info 🟢 낮음 테넌트 마스터 권한
구독관리 /subscription 🟢 낮음 테넌트 마스터 권한
결제내역 /payment-history 🟢 낮음 결제 조회 권한
알림설정 /settings/notification-settings 🟢 낮음 사용자 설정
공과관리 /construction/project/utility-management 🟢 낮음 건설 권한
우선순위 3 - LOW (18개)
페이지 경로 복잡도 작업 내용
QMS /quality/qms 🔴 높음 복잡한 상태 관리
종합경영분석 /reports/comprehensive-analysis 🟡 중간 보고서 조회 권한
보고서 메인 /reports 🟢 낮음 보고서 접근 권한
모바일 출퇴근 /hr/attendance 🟢 낮음 사용자 본인 권한
일일 일보 /accounting/daily-report 🟢 낮음 조회 권한
미수금 현황 /accounting/receivables-status 🟢 낮음 조회 권한
작업인력현황 /construction/project/worker-status 🟢 낮음 건설 권한
카테고리관리 /construction/order/base-info/categories 🟢 낮음 건설 기준정보
건설 대시보드 /construction/dashboard 🟡 중간 건설 권한
dev 페이지들 /dev/* 🟢 낮음 개발용 (권한 제외 가능)
Catch-all /[...slug] 🟢 낮음 동적 라우트
동적 게시판들 /boards/[boardCode]/* 🟡 중간 동적 권한
기타 나머지 🟢 낮음 단순 권한 체크

3.4.5 수동 적용 코드 패턴

'use client';
import { usePermission } from '@/hooks/usePermission';
import { AccessDenied } from '@/components/common/AccessDenied';

export default function MyPage() {
  const { canView, canCreate, canUpdate, canDelete, isLoading } = usePermission('MENU_CODE');

  if (isLoading) {
    return <div>로딩 ...</div>;
  }

  if (!canView) {
    return <AccessDenied />;
  }

  return (
    <div>
      {canCreate && <CreateButton />}
      {canUpdate && <EditButton />}
      {canDelete && <DeleteButton />}
    </div>
  );
}

3.4.6 수동 적용이 필요한 이유

  • 특수 권한 로직 (승인 워크플로우 등)
  • 조건부 필드 표시/숨김
  • 복합 권한 체크 (여러 메뉴 권한 조합)
  • 목록 페이지의 행 단위 권한
  • 템플릿을 사용하지 않는 특수 UI (트리, 아코디언, 대시보드)

4. 메뉴 코드 매핑 규칙

4.1 URL → 메뉴 코드 매핑

URL 패턴 메뉴 코드 (예상)
/sales/order-management order-management
/sales/client-management client-management
/sales/quote-management quote-management
/hr/employee-management employee-management
/settings/permissions permission-management

4.2 확인 필요 사항

  • 백엔드 메뉴 트리의 code 값 목록 확인
  • URL과 메뉴 코드 매핑 규칙 확정
  • 하위 메뉴 권한 상속 규칙 확인

5. 권한 캐싱 전략 ( 확정)

5.1 확정된 전략: 로그인 시 1회 로드

항목 내용
전략 로그인 시 1회 로드
권한 반영 시점 재로그인 시 적용
API 호출 최소 (로그인 시 1회)
성능 좋음

선택 이유:

  • 권한 부여 전까지는 아무것도 할 수 없음
  • 권한 변경은 자주 발생하지 않음
  • 재로그인으로 변경된 권한 적용 (사용자 혼란 없음)

5.2 구현 코드

// 로그인 성공 시 권한 로드
const PermissionProvider = ({ children }) => {
  const { user, isAuthenticated } = useAuth();
  const [permissions, setPermissions] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    if (isAuthenticated && user?.id) {
      loadPermissions(user.id);
    }
  }, [isAuthenticated, user?.id]);

  const loadPermissions = async (userId: number) => {
    setIsLoading(true);
    const result = await getMyPermissions(userId);
    if (result.success) {
      setPermissions(transformToFlatPermissions(result.data));
    }
    setIsLoading(false);
  };

  return (
    <PermissionContext.Provider value={{ permissions, isLoading }}>
      {children}
    </PermissionContext.Provider>
  );
};

6. 구현 체크리스트

Phase 1: 기반 구조 (파일 6개)

  • 백엔드에 /api/v1/my-permissions API 요청 → 기존 API 활용 (2025-01-21 확인)
  • src/lib/permissions/types.ts 생성
  • src/lib/permissions/actions.ts 생성 (Server Action)
  • src/lib/permissions/utils.ts 생성 (트리→flat 변환 유틸)
  • src/contexts/PermissionContext.tsx 생성
  • src/hooks/usePermission.ts 생성
  • RootProvider에 PermissionProvider 추가

Phase 2: Config 확장 (파일 48개)

  • DetailConfig 타입에 permission 필드 추가
  • ListConfig 타입에 permission 필드 추가 (UniversalListPage용)
  • 46개 Config 파일menuCode 추가
    • 회계 (8개): badDebtConfig, billConfig, depositDetailConfig, purchaseConfig, salesConfig, vendorConfig, vendorLedgerConfig, withdrawalDetailConfig
    • 건설 (15개): biddingConfig, contractConfig, estimateConfig, handoverReportConfig, issueConfig, itemConfig, laborDetailConfig, constructionConfig, orderConfig, partnerConfig, pricingDetailConfig, progressBillingConfig, siteBriefingConfig, siteConfig, structureReviewConfig
    • 기타 (23개): 나머지 Config 파일

Phase 3: 공통 컴포넌트 (파일 2개)

  • PermissionGuard 컴포넌트 생성
  • AccessDenied 페이지 생성

Phase 4-A: 템플릿 수정 (파일 2개 → 165개+ 페이지 자동 적용)

  • IntegratedDetailTemplate에 자동 권한 체크 추가 (101개+ 페이지)
  • UniversalListPage에 자동 권한 체크 추가 (64개 페이지)

Phase 4-B: 개별 페이지 수동 적용 (41개 페이지)

  • 우선순위 1 - HIGH (8개): 대시보드, 설정 페이지
  • 우선순위 2 - MEDIUM (15개): 전자결재, 게시판, 마스터데이터
  • 우선순위 3 - LOW (18개): QMS, 보고서, 기타

7. 예상 작업량

7.1 Phase별 작업량

Phase 작업 파일 수 영향 페이지 난이도
1 기반 구조 6개 신규 전체 🟡 중간
2 Config 확장 48개 수정 템플릿 사용 페이지 🟢 낮음 (반복 작업)
3 공통 컴포넌트 2개 신규 전체 🟢 낮음
4-A 템플릿 수정 2개 수정 165개+ 자동 🟡 중간
4-B 개별 페이지 41개 수정 41개 🟡~🔴

7.2 개별 페이지 작업량 상세

우선순위 페이지 수 복잡도 작업 내용
HIGH 8개 🟢~🟡 대시보드 위젯 필터링, 설정 권한 체크
MEDIUM 15개 🟢~🟡 전자결재, 게시판, 마스터데이터 권한
LOW 18개 🟢~🔴 QMS(복잡), 보고서, 기타 페이지

7.3 총 작업량 요약

📁 신규 파일: 8개 (Phase 1: 6개, Phase 3: 2개)
✏️ 수정 파일: 91개 (Config 48개 + 템플릿 2개 + 개별 41개)
📄 영향 페이지: 206개 전체

🎯 효율성:
- 템플릿 2개 수정 → 165개+ 페이지 자동 적용 (82.5배 효율)
- 총 99개 파일 수정 → 206개 페이지 보호 (2.1배 효율)

8. 의존성 및 선행 조건

8.1 백엔드 의존성

  • /api/v1/my-permissions API 구현 필요 → 기존 API 활용 ( 해결)
  • 사용 API: GET /api/v1/permissions/users/{userId}/menu-matrix

8.2 프론트엔드 의존성

  • Phase 1 → Phase 2 → Phase 3 → Phase 4 순서 준수
  • 선행 조건: 페이지 통합 작업 완료 후 진행

9. 참고 파일 위치

구분 파일 경로
권한 타입 src/components/settings/PermissionManagement/types.ts
권한 API src/components/settings/PermissionManagement/actions.ts
권한 매트릭스 UI src/components/settings/PermissionManagement/PermissionDetailClient.tsx
AuthContext src/contexts/AuthContext.tsx
메뉴 스토어 src/store/menuStore.ts
DetailConfig 타입 src/components/templates/IntegratedDetailTemplate/types.ts
UniversalListPage src/components/templates/UniversalListPage/index.tsx

10. 템플릿 사용 컴포넌트 상세 목록 (2026-01-21 추가)

10.1 UniversalListPage 사용 컴포넌트 (64개)

회계 (Accounting) - 13개

- BadDebtCollection/index.tsx
- BillManagement/index.tsx, BillManagementClient.tsx
- DepositManagement/index.tsx
- ExpectedExpenseManagement/index.tsx
- PurchaseManagement/index.tsx
- SalesManagement/index.tsx
- VendorLedger/index.tsx
- VendorManagement/index.tsx, VendorManagementClient.tsx
- WithdrawalManagement/index.tsx
- BankTransactionInquiry/index.tsx
- CardTransactionInquiry/index.tsx

HR - 5개

- AttendanceManagement/index.tsx
- CardManagement/index.tsx, CardManagementUnified.tsx
- EmployeeManagement/index.tsx
- SalaryManagement/index.tsx
- VacationManagement/index.tsx

건설 (Construction) - 17개

- bidding/BiddingListClient.tsx
- contract/ContractListClient.tsx
- estimates/EstimateListClient.tsx
- handover-report/HandoverReportListClient.tsx
- issue-management/IssueManagementListClient.tsx
- item-management/ItemManagementClient.tsx
- labor-management/LaborManagementClient.tsx
- management/ConstructionManagementListClient.tsx
- order-management/OrderManagementListClient.tsx, OrderManagementUnified.tsx
- partners/PartnerListClient.tsx
- pricing-management/PricingListClient.tsx
- progress-billing/ProgressBillingManagementListClient.tsx
- site-briefings/SiteBriefingListClient.tsx
- site-management/SiteManagementListClient.tsx
- structure-review/StructureReviewListClient.tsx
- utility-management/UtilityManagementListClient.tsx
- worker-status/WorkerStatusListClient.tsx

자재/생산/품질/유통 - 7개

- material/StockStatus/StockStatusList.tsx
- material/ReceivingManagement/ReceivingList.tsx
- production/WorkOrders/WorkOrderList.tsx
- production/WorkResults/WorkResultList.tsx
- quality/InspectionManagement/InspectionList.tsx
- outbound/ShipmentManagement/ShipmentList.tsx

기타 - 22개

- pricing/PricingListClient.tsx
- process-management/ProcessListClient.tsx
- items/ItemListClient.tsx
- quotes/QuoteManagementClient.tsx
- settings/PermissionManagement/index.tsx
- settings/AccountManagement/index.tsx
- settings/PaymentHistoryManagement/index.tsx, PaymentHistoryClient.tsx
- settings/PopupManagement/PopupList.tsx
- board/BoardList/index.tsx, BoardListUnified.tsx
- board/BoardManagement/index.tsx
- customer-center/NoticeManagement/NoticeList.tsx
- customer-center/EventManagement/EventList.tsx
- customer-center/InquiryManagement/InquiryList.tsx
- approval/ApprovalBox/index.tsx
- approval/DraftBox/index.tsx
- approval/ReferenceBox/index.tsx

10.2 IntegratedDetailTemplate 사용 컴포넌트 (101개+)

회계 (Accounting) - 19개

- BadDebtCollection/BadDebtDetail.tsx
- BillManagement/BillDetail.tsx
- DepositManagement/DepositDetailClientV2.tsx
- PurchaseManagement/PurchaseDetail.tsx
- SalesManagement/SalesDetail.tsx
- VendorLedger/VendorLedgerDetail.tsx
- VendorManagement/VendorDetail.tsx, VendorDetailClient.tsx
- WithdrawalManagement/WithdrawalDetailClientV2.tsx

건설 (Construction) - 40개+

- bidding/BiddingDetailForm.tsx
- contract/ContractDetailForm.tsx
- estimates/EstimateDetailForm.tsx
- handover-report/HandoverReportDetailForm.tsx
- issue-management/IssueDetailForm.tsx
- item-management/ItemDetailClient.tsx
- labor-management/LaborDetailClient.tsx
- management/ConstructionDetailClient.tsx
- order-management/OrderDetailForm.tsx
- partners/PartnerForm.tsx
- pricing-management/PricingDetailClient.tsx
- progress-billing/ProgressBillingDetailForm.tsx
- site-briefings/SiteBriefingForm.tsx
- site-management/SiteDetailForm.tsx
- structure-review/StructureReviewDetailForm.tsx

HR/클라이언트/고객센터 - 15개+

- hr/EmployeeManagement/EmployeeDetail.tsx, EmployeeForm.tsx
- hr/CardManagement/CardDetail.tsx
- clients/ClientDetailClientV2.tsx, ClientRegistration.tsx
- customer-center/NoticeManagement/NoticeDetail.tsx
- customer-center/EventManagement/EventDetail.tsx
- customer-center/InquiryManagement/InquiryDetail.tsx, InquiryForm.tsx

자재/생산/품질/유통 - 12개+

- material/ReceivingManagement/ReceivingDetail.tsx, InspectionCreate.tsx
- material/StockStatus/StockStatusDetail.tsx
- production/WorkOrders/WorkOrderCreate.tsx, WorkOrderDetail.tsx, WorkOrderEdit.tsx
- quality/InspectionManagement/InspectionCreate.tsx, InspectionDetail.tsx
- outbound/ShipmentManagement/ShipmentCreate.tsx, ShipmentDetail.tsx, ShipmentEdit.tsx

기타 - 15개+

- orders/OrderRegistration.tsx, OrderSalesDetailEdit.tsx, OrderSalesDetailView.tsx
- quotes/QuoteRegistration.tsx
- process-management/ProcessForm.tsx
- settings/PermissionManagement/PermissionDetail.tsx
- settings/PopupManagement/PopupDetailClientV2.tsx
- board/BoardForm/index.tsx
- approval/DocumentCreate/index.tsx

11. 검증 체크리스트

Phase 1 완료 후 검증

  • PermissionContext가 로그인 시 권한 로드
  • usePermission 훅이 올바른 권한 반환
  • 권한 없는 사용자에게 false 반환

Phase 2 완료 후 검증

  • 모든 46개 Config에 menuCode 추가됨
  • TypeScript 타입 에러 없음
  • 기존 기능 영향 없음 (backward compatible)

Phase 4 완료 후 검증

  • 템플릿 사용 페이지 165개+ 권한 체크 작동
  • 개별 페이지 41개 권한 체크 작동
  • 권한 없는 사용자 AccessDenied 표시
  • 권한 있는 사용자 모든 기능 정상

문서 업데이트 이력:

  • 2025-01-20: 최초 작성
  • 2025-01-21: 백엔드 API 확정, 캐싱 전략 확정
  • 2026-01-21: 전체 페이지 분석 추가 (206개), Config 파일 46개 확인, 개별 작업 필요 페이지 41개 목록화
  • 2026-01-23: 공통화/추상화 효율 분석 추가, page.tsx vs 컴포넌트 레벨 관점 차이 설명, 권한 적용 구조도 추가