195 lines
6.4 KiB
Markdown
195 lines
6.4 KiB
Markdown
# 조직도 서비스 이관 기획서
|
|
|
|
> **작성일**: 2026-03-22
|
|
> **상태**: API 구현 완료, React 문서 제공
|
|
> **대상**: MNG → API + React (서비스 이관)
|
|
> **위치**: 서비스 > 인사관리 > 조직도
|
|
|
|
---
|
|
|
|
## 1. 개요
|
|
|
|
### 1.1 목적
|
|
|
|
MNG 백오피스의 조직도 관리 기능을 서비스(API + React)로 이관한다.
|
|
기존 MNG의 Alpine.js + SortableJS 기반 UI를 REST API + React 구조로 재구현하며,
|
|
멀티테넌트 격리를 API 레이어에서 강화한다.
|
|
|
|
### 1.2 배경
|
|
|
|
- MNG `R&D > 조직도 관리` 메뉴로 v1.0 구현 완료 (2026-03-06)
|
|
- 부서 CRUD + 트리 + 사용자 배치 API는 이미 존재 (`DepartmentController`)
|
|
- 조직도 전용 기능(직원 일괄 이동, 부서 순서/계층 변경, 숨기기)이 API에 없었음
|
|
- MNG는 `session('selected_tenant_id')` 수동 격리 → API는 `BelongsToTenant` 글로벌 스코프
|
|
|
|
### 1.3 이관 범위
|
|
|
|
| 구분 | MNG (현재) | API + React (이관 후) |
|
|
|------|-----------|---------------------|
|
|
| **백엔드** | RdController 직접 로직 | OrgChartService + OrgChartController + FormRequest |
|
|
| **프론트** | Alpine.js + SortableJS | React (Next.js) + @dnd-kit |
|
|
| **인증** | 세션 기반 | Bearer 토큰 + `BelongsToTenant` |
|
|
| **데이터** | `withoutGlobalScopes()` 수동 | 글로벌 스코프 자동 격리 |
|
|
| **API 문서** | 없음 | Swagger |
|
|
|
|
---
|
|
|
|
## 2. 현재 MNG 기능 분석
|
|
|
|
### 2.1 MNG 엔드포인트 (RdController)
|
|
|
|
| Route | Method | 설명 |
|
|
|-------|--------|------|
|
|
| `/rd/org-chart` | GET | 조직도 페이지 (트리+직원+회사정보) |
|
|
| `/rd/org-chart/assign` | POST | 직원 부서 배치 |
|
|
| `/rd/org-chart/unassign` | POST | 직원 미배치 처리 |
|
|
| `/rd/org-chart/reorder` | POST | 직원 일괄 이동 |
|
|
| `/rd/org-chart/reorder-depts` | POST | 부서 트리 순서/계층 변경 |
|
|
| `/rd/org-chart/toggle-hide` | POST | 부서 숨기기/표시 토글 |
|
|
|
|
### 2.2 데이터 모델
|
|
|
|
- **부서**: `departments` 테이블 (자기참조 `parent_id`, `sort_order`, `options.orgchart_hidden`)
|
|
- **직원**: `tenant_user_profiles` 테이블 (`department_id`로 소속 관리)
|
|
- **회사**: `tenants` 테이블 (`company_name`, `ceo_name`)
|
|
|
|
### 2.3 기존 API 구현 (DepartmentController)
|
|
|
|
| 기능 | 상태 |
|
|
|------|:----:|
|
|
| 부서 CRUD | ✅ |
|
|
| 부서 트리 조회 (`/tree`) | ✅ |
|
|
| 사용자 배정 (`attachUser/detachUser`) | ✅ (department_user 피벗) |
|
|
| 조직도 전용 기능 | ❌ → **이번 이관 대상** |
|
|
|
|
---
|
|
|
|
## 3. API 설계
|
|
|
|
### 3.1 신규 엔드포인트 (`/v1/org-chart`)
|
|
|
|
| Method | Path | 설명 |
|
|
|--------|------|------|
|
|
| GET | `/v1/org-chart` | 조직도 전체 (트리+직원+통계) |
|
|
| GET | `/v1/org-chart/stats` | 통계 (전체/배치/미배치) |
|
|
| GET | `/v1/org-chart/unassigned?q=` | 미배치 직원 |
|
|
| POST | `/v1/org-chart/assign` | 직원 부서 배치 |
|
|
| POST | `/v1/org-chart/unassign` | 직원 미배치 처리 |
|
|
| PUT | `/v1/org-chart/reorder-employees` | 직원 일괄 이동 |
|
|
| PUT | `/v1/org-chart/reorder-departments` | 부서 순서/계층 변경 |
|
|
| PATCH | `/v1/org-chart/departments/{id}/toggle-hide` | 부서 숨기기 토글 |
|
|
|
|
### 3.2 주요 응답 구조
|
|
|
|
**GET `/v1/org-chart`**:
|
|
```json
|
|
{
|
|
"company": { "name": "...", "ceo_name": "..." },
|
|
"departments": [{ "id": 1, "name": "...", "children": [...], "employees": [...] }],
|
|
"hidden_departments": [{ "id": 5, "name": "..." }],
|
|
"unassigned": [{ "id": 12, "display_name": "...", "position_label": "..." }],
|
|
"stats": { "total": 50, "assigned": 42, "unassigned": 8 }
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 4. API 구현 상세
|
|
|
|
### 4.1 파일 구조
|
|
|
|
```
|
|
api/
|
|
├── app/Http/Controllers/Api/V1/OrgChartController.php (신규)
|
|
├── app/Http/Requests/OrgChart/
|
|
│ ├── AssignRequest.php
|
|
│ ├── UnassignRequest.php
|
|
│ ├── ReorderEmployeesRequest.php
|
|
│ ├── ReorderDepartmentsRequest.php
|
|
│ └── ToggleHideRequest.php
|
|
├── app/Services/OrgChartService.php (신규)
|
|
├── app/Models/Tenants/Department.php (수정: options cast)
|
|
├── app/Swagger/v1/OrgChartApi.php (신규)
|
|
└── routes/api/v1/hr.php (수정: 라우트 추가)
|
|
```
|
|
|
|
### 4.2 설계 결정
|
|
|
|
- **별도 OrgChartController/Service 분리**: 기존 DepartmentController(13개 메서드)와 관심사 분리
|
|
- **TenantUserProfile.department_id 기반**: MNG와 동일하게 직원의 소속 부서 필드 직접 사용
|
|
- **순환 참조 방지**: `reorderDepartments`에서 `parent_id` 변경 시 자손→조상 순환 검증
|
|
|
|
---
|
|
|
|
## 5. React 구현 (FE 가이드)
|
|
|
|
> **별도 문서**: `docs/frontend/v1/org-chart-fe-guide.md`
|
|
|
|
---
|
|
|
|
## 6. 인증 및 권한
|
|
|
|
### 6.1 React → API
|
|
|
|
- `authenticatedFetch` 사용 (HttpOnly 쿠키 기반 Sanctum)
|
|
- `auth:sanctum` 미들웨어 자동 적용 (HR 라우트 그룹)
|
|
|
|
### 6.2 MNG → API (해당 없음)
|
|
|
|
- MNG는 기존 코드를 유지하고 자체 DB 직접 접근
|
|
- 이관 완료 후 MNG 메뉴를 숨기고 React로 안내
|
|
|
|
---
|
|
|
|
## 7. 구현 순서
|
|
|
|
| Phase | 작업 | 상태 |
|
|
|-------|------|:----:|
|
|
| 1 | Department 모델 `options` cast 추가 | ✅ 완료 |
|
|
| 2 | OrgChartService + FormRequest 5개 생성 | ✅ 완료 |
|
|
| 3 | OrgChartController + Route 등록 | ✅ 완료 |
|
|
| 4 | Swagger 문서 (OrgChartApi.php) | ✅ 완료 |
|
|
| 5 | React FE 구현 | 📋 문서 제공 |
|
|
| 6 | 통합 테스트 + MNG 메뉴 전환 | ⏳ 대기 |
|
|
|
|
---
|
|
|
|
## 8. MNG 기존 코드 처리
|
|
|
|
- MNG `RdController.orgChart*` 메서드 → **유지** (삭제하지 않음)
|
|
- React 구현 완료 후 MNG 메뉴에서 조직도를 비활성화하고 서비스로 안내
|
|
|
|
---
|
|
|
|
## 9. 체크리스트
|
|
|
|
### API
|
|
- [x] `OrgChartService` 8개 메서드 구현
|
|
- [x] `OrgChartController` FormRequest DI 적용
|
|
- [x] 순환 참조 방지 검증 (reorderDepartments)
|
|
- [x] `Department` 모델 `options` cast 추가
|
|
- [x] Swagger 문서 생성 확인
|
|
- [x] Pint 포맷팅 통과
|
|
|
|
### React
|
|
- [ ] `org-chart-fe-guide.md` 기반 구현
|
|
- [ ] 드래그 앤 드롭 (부서/직원)
|
|
- [ ] 미배치 직원 패널
|
|
- [ ] 부서 숨기기/복원
|
|
|
|
---
|
|
|
|
## 관련 문서
|
|
|
|
| 문서 | 경로 |
|
|
|------|------|
|
|
| 조직도 시스템 (MNG) | `projects/org-chart/README.md` |
|
|
| 부서 API 규칙 | `rules/department-tree-api.md` |
|
|
| 직원 API 규칙 | `rules/employee-api.md` |
|
|
| React FE 가이드 | `frontend/v1/org-chart-fe-guide.md` |
|
|
| 이관 현황 | `system/migration-status.md` |
|
|
|
|
---
|
|
|
|
**최종 업데이트**: 2026-03-22
|