# 프론트엔드 권한 시스템 구현 체크리스트

> 작성일: 2026-01-12
> 참고 문서: [ANALYSIS-2026-01-07] permission-system-status.md

---

## 구현 목표

로그인한 사용자의 권한에 따라 UI 요소(버튼, 메뉴 등)를 동적으로 표시/숨김 처리

---

## Phase 1: 기반 구조 구축

### 1.1 타입 정의
- [ ] `src/types/permission.ts` 생성
  - [ ] `PermissionAction` 타입 (view, create, update, delete, approve)
  - [ ] `PermissionState` 타입 (allow, deny, none)
  - [ ] `MenuPermission` 인터페이스 (API 응답 구조)
  - [ ] `PermissionMatrix` 인터페이스 (트리 → 플랫 변환용)

### 1.2 환경 변수 설정
- [ ] `.env.local`에 `NEXT_PUBLIC_ENABLE_AUTHORIZATION=false` 추가
- [ ] `.env.example`에 동일 항목 추가 (문서화)

---

## Phase 2: 상태 관리

### 2.1 Permission Store 생성
- [ ] `src/store/permissionStore.ts` 생성
  - [ ] 상태 정의
    - [ ] `permissions`: URL 기반 권한 맵 (`Record<string, PermissionActions>`)
    - [ ] `isLoaded`: 권한 로딩 완료 여부
    - [ ] `isEnabled`: 환경 변수 기반 활성화 여부
  - [ ] 액션 정의
    - [ ] `setPermissions(tree)`: API 응답 트리를 플랫 맵으로 변환 저장
    - [ ] `clearPermissions()`: 로그아웃 시 초기화
    - [ ] `hasPermission(url, action)`: 권한 체크 함수
  - [ ] persist 미들웨어 적용 (localStorage)

### 2.2 유틸리티 함수
- [ ] `src/lib/permission-utils.ts` 생성
  - [ ] `flattenPermissionTree(tree)`: 트리 구조를 URL 기반 플랫 맵으로 변환
  - [ ] `normalizeUrl(url)`: URL 정규화 (locale 제거 등)

---

## Phase 3: API 연동

### 3.1 Server Action 생성
- [ ] `src/lib/api/permissions/actions.ts` 생성
  - [ ] `getUserPermissions(userId)`: 권한 매트릭스 API 호출

### 3.2 로그인 플로우 연동
- [ ] 로그인 성공 후 권한 API 호출 로직 추가
  - [ ] `AuthenticatedLayout.tsx` 또는 로그인 처리 부분에서 호출
  - [ ] 권한 로딩 중 상태 처리 (로딩 UI 또는 스켈레톤)

---

## Phase 4: usePermission 훅 구현

### 4.1 훅 생성
- [ ] `src/hooks/usePermission.ts` 생성
  - [ ] 입력: 메뉴 URL 또는 메뉴명
  - [ ] 출력:
    ```typescript
    {
      canView: boolean;
      canCreate: boolean;
      canUpdate: boolean;
      canDelete: boolean;
      canApprove: boolean;
      isLoading: boolean;
    }
    ```
  - [ ] 환경 변수 비활성화 시 모두 `true` 반환

### 4.2 편의 컴포넌트 (선택사항)
- [ ] `src/components/common/PermissionGuard.tsx` 생성
  ```typescript
  <PermissionGuard menu="/sales/orders" action="create">
    <Button>등록</Button>
  </PermissionGuard>
  ```

---

## Phase 5: 적용 및 테스트

### 5.1 샘플 페이지 적용
- [ ] 테스트용 페이지 1개 선정 (예: 판매관리)
- [ ] 등록/수정/삭제 버튼에 권한 체크 적용
- [ ] 동작 확인

### 5.2 전체 적용 (점진적)
- [ ] 주요 페이지 목록 작성
- [ ] 각 페이지별 권한 적용 진행

---

## Phase 6: 예외 처리 및 UX

### 6.1 에러 처리
- [ ] 권한 API 실패 시 fallback 처리 (모두 허용 or 모두 거부)
- [ ] 네트워크 오류 시 재시도 로직

### 6.2 UX 개선
- [ ] 권한 없는 버튼: 숨김 vs 비활성화(disabled) 정책 결정
- [ ] 권한 없는 페이지 접근 시 처리 (리다이렉트 or 안내 메시지)

---

## 파일 생성 목록 요약

| 파일 경로 | 설명 |
|----------|------|
| `src/types/permission.ts` | 권한 관련 타입 정의 |
| `src/store/permissionStore.ts` | 권한 상태 관리 (Zustand) |
| `src/lib/permission-utils.ts` | 권한 유틸리티 함수 |
| `src/lib/api/permissions/actions.ts` | 권한 API Server Action |
| `src/hooks/usePermission.ts` | 권한 체크 훅 |
| `src/components/common/PermissionGuard.tsx` | 권한 가드 컴포넌트 (선택) |

---

## 의존성

- 추가 패키지 설치 불필요 (기존 Zustand 활용)

---

## 주의사항

1. **환경 변수 기본값**: 개발 중에는 `NEXT_PUBLIC_ENABLE_AUTHORIZATION=false`로 비활성화
2. **플랫 맵 변환**: API 응답이 트리 구조이므로 URL 기반 플랫 맵으로 변환 필요
3. **URL 정규화**: locale prefix (`/ko`, `/en`) 제거하여 비교
4. **로그아웃 시 초기화**: permissionStore 클리어 필수

---

## 예상 작업 순서

```
Phase 1 (타입/환경변수) → Phase 2 (스토어) → Phase 3 (API 연동)
    → Phase 4 (훅) → Phase 5 (적용) → Phase 6 (예외처리)
```

---

*체크리스트 완료 후 이 문서를 archive로 이동*