Files
sam-docs/dev/dev_plans/archive/l2-permission-management-plan.md
권혁성 db63fcff85 refactor: [docs] 팀별 폴더 구조 재편 (공유/개발/프론트/기획)
- 개발팀 전용 폴더 dev/ 생성 (standards, guides, quickstart, changes, deploys, data, history, dev_plans 이동)
- 프론트엔드 전용 폴더 frontend/ 생성 (api/ → frontend/api-specs/)
- 기획팀 폴더 requests/ 생성
- plans/ → dev/dev_plans/ 이름 변경
- README.md 신규 (사람용 안내), INDEX.md 재작성 (Claude Code용)
- resources.md 신규 (노션 링크용, assets/brochure 이관 예정)
- CURRENT_WORKS.md 삭제, TODO.md → dev/ 이동
- 전체 참조 경로 업데이트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 16:46:03 +09:00

378 lines
13 KiB
Markdown

# 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 스킬로 생성되었습니다.*