# L-2 권한관리 Mock → API 연동 계획 > **작성일**: 2025-12-30 > **목적**: React 권한관리 페이지의 Mock 데이터를 API 연동으로 전환 > **기준 문서**: mng.sam.kr/role-permissions > **상태**: ✅ 완료 - Phase 1~4 전체 완료 --- ## 📍 현재 진행 상태 | 항목 | 내용 | |------|------| | **마지막 완료 작업** | Phase 4 React 연동 완료 | | **다음 작업** | 완료 (테스트 후 운영 배포) | | **진행률** | 12/12 (100%) | | **마지막 업데이트** | 2025-12-30 --- ## 1. 개요 ### 1.1 배경 현재 React의 권한관리 페이지(`/settings/permissions`)는 `localStorage`와 `defaultPermissions` Mock 데이터를 사용하고 있습니다. mng 프로젝트에는 이미 완전한 역할-권한 관리 시스템이 구현되어 있으므로, api 프로젝트에 동일한 API를 개발하고 React에서 연동해야 합니다. **문제점:** - React는 `localStorage`에 권한 데이터 저장 (새로고침/브라우저 변경 시 데이터 손실) - 실제 DB 연동 없음 - 역할 숨김(is_hidden) 기능이 DB 스키마에 없음 ### 1.2 기준 원칙 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 🎯 핵심 원칙 │ ├─────────────────────────────────────────────────────────────────┤ │ 1. React → api.sam.kr만 호출 (mng 직접 호출 금지) │ │ 2. mng의 RoleService/RolePermissionService 로직 참조하여 api에 재구현 │ │ 3. Spatie Permission 패키지 활용 (기존 테이블 구조 유지) │ │ 4. Multi-tenant 지원 필수 (BelongsToTenant) │ └─────────────────────────────────────────────────────────────────┘ ``` ### 1.3 변경 승인 정책 | 분류 | 예시 | 승인 | |------|------|------| | ✅ 즉시 가능 | API 엔드포인트 추가, 타입 정의, 문서 수정 | 불필요 | | ⚠️ 컨펌 필요 | DB 마이그레이션 (is_hidden 컬럼), 기존 API 수정 | **필수** | | 🔴 금지 | roles 테이블 구조 대폭 변경, 기존 권한 삭제 | 별도 협의 | ### 1.4 준수 규칙 - `docs/quickstart/quick-start.md` - 빠른 시작 가이드 - `docs/standards/api-rules.md` - API 개발 규칙 - `docs/standards/quality-checklist.md` - 품질 체크리스트 - `docs/specs/database-schema.md` - DB 스키마 --- ## 2. 현재 상태 분석 ### 2.1 mng 프로젝트 (기준) | 파일 | 역할 | 주요 기능 | |------|------|----------| | `RoleController.php` | 역할 CRUD 화면 | index, create, edit | | `RoleService.php` | 역할 비즈니스 로직 | getRoles, createRole, updateRole, deleteRole | | `RolePermissionController.php` | 권한 매트릭스 화면 | index (테넌트별 역할 목록) | | `RolePermissionService.php` | 권한 매트릭스 로직 | togglePermission, allowAll, denyAll, getMenuTree | | `Role.php` (Model) | 역할 모델 | tenant, permissions, users 관계 | **mng의 역할 필드:** ```php $fillable = ['tenant_id', 'name', 'description', 'guard_name']; ``` **⚠️ 숨김 기능 없음**: mng에도 `is_hidden` 필드가 없음 ### 2.2 React 프로젝트 (현재) | 파일 | 현재 상태 | 문제점 | |------|----------|--------| | `index.tsx` | `localStorage` + `defaultPermissions` | 실제 DB 연동 없음 | | `types.ts` | `Permission` 타입 정의 | `status: 'active' | 'hidden'` 있음 | | `PermissionDetail.tsx` | 메뉴별 권한 설정 | Mock 데이터 사용 | **React의 Permission 타입:** ```typescript interface Permission { id: number; name: string; status: 'active' | 'hidden'; // ← DB에 없음! menuPermissions: MenuPermission[]; createdAt: string; } ``` ### 2.3 api 프로젝트 (현재) - **Role 관련 API 없음** (개발 필요) - `shared/Models/Role.php` 존재 여부 확인 필요 ### 2.4 DB 스키마 (roles 테이블) ```sql roles (11 컬럼): - id (PK) - tenant_id (FK → tenants.id) - name - guard_name (default: 'web') - description - created_by, updated_by, deleted_by - created_at, updated_at, deleted_at -- ⚠️ is_hidden 컬럼 없음! 추가 필요 ``` --- ## 3. 대상 범위 ### 3.1 Phase 1: DB 스키마 수정 | # | 작업 항목 | 상태 | 비고 | |---|----------|:----:|------| | 1.1 | roles 테이블에 `is_hidden` 컬럼 추가 | ✅ | `2025_12_30_160802_add_is_hidden_to_roles_table.php` 생성완료, 실행대기 | | 1.2 | 기존 역할 데이터 기본값 설정 (is_hidden = false) | ✅ | 마이그레이션에 포함 | ### 3.2 Phase 2: api 프로젝트 - Role CRUD API | # | 작업 항목 | 상태 | 비고 | |---|----------|:----:|------| | 2.1 | Role 모델 생성/수정 | ✅ | shared/Models/Role.php | | 2.2 | RoleService 생성 | ✅ | `api/app/Services/RoleService.php` | | 2.3 | RoleController 생성 | ✅ | `api/app/Http/Controllers/Api/V1/RoleController.php` | | 2.4 | RoleFormRequest 생성 | ⏳ | StoreRoleRequest, UpdateRoleRequest 미생성 | | 2.5 | routes/api.php 라우트 추가 | ✅ | 5개 CRUD 라우트 등록완료 | | 2.6 | Swagger 문서 작성 | ✅ | `api/app/Swagger/v1/RoleApi.php` | ### 3.3 Phase 3: api 프로젝트 - 권한 매트릭스 API | # | 작업 항목 | 상태 | 비고 | |---|----------|:----:|------| | 3.1 | RolePermissionController 생성 | ✅ | `api/app/Http/Controllers/Api/V1/RolePermissionController.php` | | 3.2 | 권한 목록 조회 API | ✅ | GET /roles/{id}/permissions | | 3.3 | 권한 부여 API | ✅ | POST /roles/{id}/permissions | | 3.4 | 권한 회수/동기화 API | ✅ | DELETE, PUT /roles/{id}/permissions/sync | | 3.5 | Swagger 문서 작성 | ✅ | `api/app/Swagger/v1/RolePermissionApi.php` | ### 3.4 Phase 4: React 연동 ✅ | # | 작업 항목 | 상태 | 비고 | |---|----------|:----:|------| | 4.1 | actions.ts 생성 | ✅ | 12개 Server Actions (fetchRoles, createRole, updateRole, deleteRole 등) | | 4.2 | types.ts 수정 | ✅ | ApiResponse, Role, RoleStats, MenuTreeItem, PermissionMatrix 타입 추가 | | 4.3 | index.tsx 수정 (목록) | ✅ | localStorage → API 연동, 로딩/에러 상태, toast 알림 | | 4.4 | PermissionDetailClient.tsx 수정 (상세/권한매트릭스) | ✅ | 역할 CRUD, 권한 토글, 전체 허용/거부/초기화 | | 4.5 | Mock 데이터 제거 | ✅ | defaultPermissions 삭제, API 기반으로 전환 | --- ## 4. API 설계 ### 4.1 Role CRUD API | Method | Endpoint | 설명 | Request | Response | |--------|----------|------|---------|----------| | GET | `/api/v1/roles` | 역할 목록 | `?search=&is_hidden=` | `{ data: Role[], meta: Pagination }` | | GET | `/api/v1/roles/{id}` | 역할 상세 | - | `{ data: Role }` | | POST | `/api/v1/roles` | 역할 생성 | `{ name, description, is_hidden }` | `{ data: Role }` | | PUT | `/api/v1/roles/{id}` | 역할 수정 | `{ name, description, is_hidden }` | `{ data: Role }` | | DELETE | `/api/v1/roles/{id}` | 역할 삭제 | - | `{ message }` | ### 4.2 권한 매트릭스 API | Method | Endpoint | 설명 | Request | Response | |--------|----------|------|---------|----------| | GET | `/api/v1/roles/{id}/menus` | 메뉴 트리 + 권한 상태 | - | `{ data: MenuWithPermissions[] }` | | POST | `/api/v1/roles/{id}/permissions/toggle` | 권한 토글 | `{ menu_id, permission_type }` | `{ data: { value: boolean } }` | | POST | `/api/v1/roles/{id}/permissions/allow-all` | 전체 허용 | - | `{ message }` | | POST | `/api/v1/roles/{id}/permissions/deny-all` | 전체 거부 | - | `{ message }` | | POST | `/api/v1/roles/{id}/permissions/reset` | 기본값 초기화 | - | `{ message }` | ### 4.3 Role 응답 타입 ```typescript interface Role { id: number; tenant_id: number; name: string; description: string | null; guard_name: string; is_hidden: boolean; // ← 신규 필드 permissions_count: number; // ← 권한 개수 users_count: number; // ← 사용자 수 created_at: string; updated_at: string; } interface MenuWithPermissions { id: number; name: string; parent_id: number | null; depth: number; has_children: boolean; permissions: { view: boolean; create: boolean; update: boolean; delete: boolean; approve: boolean; export: boolean; manage: boolean; }; } ``` --- ## 5. 상세 작업 내용 ### 5.1 Phase 1: DB 스키마 수정 ✅ #### 1.1 roles 테이블에 is_hidden 컬럼 추가 - **상태**: ✅ 파일 생성완료 (실행 대기) - **마이그레이션 파일**: `2025_12_30_160802_add_is_hidden_to_roles_table.php` - **컬럼 정의**: `boolean is_hidden default false after description` - **영향**: api, mng 모두 적용 ### 5.2 Phase 2: Role CRUD API ✅ #### 생성된 파일 | 파일 | 경로 | |------|------| | RoleController | `api/app/Http/Controllers/Api/V1/RoleController.php` | | RoleService | `api/app/Services/RoleService.php` | | RoleApi Swagger | `api/app/Swagger/v1/RoleApi.php` | #### 등록된 라우트 (5개) ``` GET /api/v1/roles → index POST /api/v1/roles → store GET /api/v1/roles/{id} → show PATCH /api/v1/roles/{id} → update DELETE /api/v1/roles/{id} → destroy ``` ### 5.3 Phase 3: 권한 매트릭스 API ✅ #### 생성된 파일 | 파일 | 경로 | |------|------| | RolePermissionController | `api/app/Http/Controllers/Api/V1/RolePermissionController.php` | | RolePermissionApi Swagger | `api/app/Swagger/v1/RolePermissionApi.php` | #### 등록된 라우트 (4개) ``` GET /api/v1/roles/{id}/permissions → index POST /api/v1/roles/{id}/permissions → grant DELETE /api/v1/roles/{id}/permissions → revoke PUT /api/v1/roles/{id}/permissions/sync → sync ``` --- ## 6. 컨펌 대기 목록 > API 내부 로직 변경 등 승인 필요 항목 | # | 항목 | 변경 내용 | 영향 범위 | 상태 | |---|------|----------|----------|------| | 1 | is_hidden 컬럼 추가 | roles 테이블 마이그레이션 | api, mng | ⏳ 대기 | --- ## 7. 파일 구조 (예상) ### 7.1 api 프로젝트 ``` api/app/ ├── Http/ │ ├── Controllers/ │ │ └── RoleController.php ← 🆕 생성 │ └── Requests/ │ ├── StoreRoleRequest.php ← 🆕 생성 │ └── UpdateRoleRequest.php ← 🆕 생성 ├── Models/ │ └── Role.php ← 🔄 수정 (is_hidden 추가) └── Services/ ├── RoleService.php ← 🆕 생성 └── RolePermissionService.php ← 🆕 생성 api/database/migrations/ └── xxxx_add_is_hidden_to_roles_table.php ← 🆕 생성 api/routes/ └── api.php ← 🔄 수정 (라우트 추가) ``` ### 7.2 React 프로젝트 ``` react/src/components/settings/PermissionManagement/ ├── index.tsx ← 🔄 수정 (API 연동) ├── types.ts ← 🔄 수정 (타입 매핑) ├── actions.ts ← 🆕 생성 ├── PermissionDetail.tsx ← 🔄 수정 (API 연동) ├── PermissionDetailClient.tsx ← 🔄 수정 └── PermissionDialog.tsx ← 🔄 수정 ``` --- ## 8. 변경 이력 | 날짜 | 항목 | 변경 내용 | 파일 | 승인 | |------|------|----------|------|------| | 2025-12-30 | Phase 1~3 | API 개발 완료 (마이그레이션, Controller, Service, Swagger, 라우트) | 다수 | ✅ | | 2025-12-30 | Phase 4 | React 연동 완료 (actions.ts, types.ts, index.tsx, PermissionDetailClient.tsx) | react 4개 파일 | ✅ | | 2025-12-30 | 문서 | 계획 문서 초안 작성 | - | - | | 2025-12-30 | 문서 | Phase 4 완료 반영 업데이트 | - | - | --- ## 9. 참고 문서 - **빠른 시작**: `docs/quickstart/quick-start.md` - **API 규칙**: `docs/standards/api-rules.md` - **품질 체크리스트**: `docs/standards/quality-checklist.md` - **DB 스키마**: `docs/specs/database-schema.md` - **mng 권한관리**: `mng/app/Services/RoleService.php`, `RolePermissionService.php` --- ## 10. 세션 및 메모리 관리 정책 (Serena Optimized) ### 10.1 세션 시작 시 (Load Strategy) ```javascript read_memory("l2-permission-state") // 1. 상태 파악 read_memory("l2-permission-snapshot") // 2. 사고 흐름 복구 ``` ### 10.2 Serena 메모리 구조 - `l2-permission-state`: { phase, progress, next_step, last_decision } - `l2-permission-snapshot`: 현재까지의 논의 및 코드 변경점 요약 --- ## 11. 검증 결과 > 작업 완료 후 이 섹션에 검증 결과 추가 ### 11.1 테스트 케이스 | 입력값 | 예상 결과 | 실제 결과 | 상태 | |--------|----------|----------|------| | GET /api/v1/roles | 역할 목록 반환 | | ⏳ | | POST /api/v1/roles | 역할 생성 | | ⏳ | | PUT /api/v1/roles/{id} | 역할 수정 | | ⏳ | | DELETE /api/v1/roles/{id} | 역할 삭제 | | ⏳ | | GET /api/v1/roles/{id}/menus | 메뉴+권한 매트릭스 | | ⏳ | | POST /api/v1/roles/{id}/permissions/toggle | 권한 토글 | | ⏳ | ### 11.2 성공 기준 달성 현황 | 기준 | 달성 | 비고 | |------|------|------| | localStorage 제거 | ⏳ | | | 역할 CRUD API 동작 | ⏳ | | | 권한 매트릭스 API 동작 | ⏳ | | | 숨김 기능 동작 | ⏳ | | --- *이 문서는 /sc:plan 스킬로 생성되었습니다.*