# React 부서관리 기능 보완 계획 > **작성일**: 2026-03-12 > **목적**: React 부서관리(/hr/department-management)를 MNG 부서관리와 동일 기능 수준으로 보완 > **기준 문서**: `docs/rules/department-tree-api.md`, MNG DepartmentController 분석 > **상태**: 🔄 Phase 1~2 승인 완료 — 작업 대기 --- ## 📍 현재 진행 상태 | 항목 | 내용 | |------|------| | **마지막 완료 작업** | Phase 1~2 구현 완료 | | **다음 작업** | 검증 (브라우저 테스트) | | **진행률** | 7/7 (100%) — Phase 1~2 완료 | | **마지막 업데이트** | 2026-03-13 | --- ## 1. 개요 ### 1.1 배경 MNG(`mng.sam.kr/departments`)와 React(`dev.sam.kr/hr/department-management`)에 동일한 부서관리 기능이 존재하지만, React 쪽이 기능적으로 많이 부족한 상태. 관리 플랫폼이 달라도 같은 수준의 CRUD와 관리 기능을 제공해야 함. ### 1.2 현재 상태 비교 **React에 누락된 기능:** | # | 누락 기능 | 심각도 | 비고 | |---|----------|:------:|------| | 1 | 부서 코드(code) 필드 | 🔴 | 폼에 아예 없음 | | 2 | 설명(description) 필드 | 🟡 | 폼에 아예 없음 | | 3 | 정렬순서(sort_order) 필드 | 🟡 | 폼에 아예 없음 | | 4 | 활성상태(is_active) 관리 | 🔴 | 폼/리스트 모두 없음 | | 5 | 검색 필터링 | 🔴 | UI만 있고 실제 동작 안함 | | 6 | 상태 필터 (활성/비활성) | 🟡 | 없음 | | 7 | Soft Delete 복원 | 🟡 | 없음 | | 8 | 영구삭제 (슈퍼관리자) | 🟢 | 없음 (admin 전용이라 후순위 가능) | | 9 | 삭제 상태 필터 | 🟡 | 없음 | | 10 | 트리 리스트에 상태 뱃지 | 🟡 | 없음 | | 11 | 트리 리스트에 부서코드 표시 | 🟡 | 없음 | **React가 이미 잘 된 부분:** - ✅ 트리 구조 시각화 (펼치기/접기) - ✅ 통계 카드 - ✅ 행 단위 하위부서 추가 버튼 - ✅ 전체 선택/다중 선택 ### 1.3 성공 기준 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 🎯 성공 기준 │ ├─────────────────────────────────────────────────────────────────┤ │ 1. MNG에서 가능한 모든 CRUD가 React에서도 가능 │ │ 2. 부서 코드/설명/정렬순서/활성상태 필드가 폼에 포함 │ │ 3. 검색, 상태 필터가 실제 동작 │ │ 4. 삭제된 부서 복원 가능 │ │ 5. 트리 리스트에 코드, 상태 뱃지 표시 │ └─────────────────────────────────────────────────────────────────┘ ``` ### 1.4 변경 승인 정책 | 분류 | 예시 | 승인 | |------|------|------| | ✅ 즉시 가능 | 타입 확장, 필드 추가, UI 컴포넌트 수정 | 불필요 | | ⚠️ 컨펌 필요 | API 호출 추가, 새 서버액션 추가 | **필수** | | 🔴 금지 | DB 스키마 변경, API 컨트롤러 수정 | 별도 협의 | ### 1.5 기준 원칙 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 📌 원칙 │ ├─────────────────────────────────────────────────────────────────┤ │ - API 변경 최소화: 기존 /v1/departments API 그대로 활용 │ │ - React 프론트엔드 패턴 준수: Server Action, buildApiUrl 등 │ │ - 트리 구조 유지: 현재 트리 UI 장점 살리면서 필드만 보강 │ │ - MNG와 1:1 기능 매칭이 목표 (UI/UX는 React 스타일 유지) │ └─────────────────────────────────────────────────────────────────┘ ``` ### 1.6 준수 규칙 - `docs/frontend/v1/02-api-pattern.md` — API 통신 패턴 - `docs/frontend/v1/05-form-pattern.md` — 폼 패턴 (Zod + react-hook-form) - `docs/frontend/v1/03-component-design.md` — 컴포넌트 설계 - `docs/rules/department-tree-api.md` — 부서 트리 API 규칙 - `docs/dev/standards/quality-checklist.md` — 품질 체크리스트 --- ## 2. 대상 범위 ### 2.1 Phase 1: 타입 & 폼 필드 보강 (핵심) | # | 작업 항목 | 상태 | 비고 | |---|----------|:----:|------| | 1.1 | types.ts 확장 — code, description, isActive, sortOrder 추가 | ✅ | Department + DepartmentFormData + StatusFilter 추가 | | 1.2 | actions.ts — 이미 전체 필드 매핑 완료 확인 | ✅ | 변경 불필요 (ApiDepartment→DepartmentRecord 이미 완전) | | 1.3 | DepartmentDialog 폼 필드 추가 — code, description, sortOrder, isActive | ✅ | Zod v4 + react-hook-form 적용 | | 1.4 | DepartmentTreeItem에 코드, 상태 뱃지 표시 | ✅ | Badge 컴포넌트 활용 | ### 2.2 Phase 2: 검색 & 필터 (실질 기능) | # | 작업 항목 | 상태 | 비고 | |---|----------|:----:|------| | 2.1 | DepartmentToolbar 검색 실제 동작 구현 | ✅ | 클라이언트사이드 트리 필터링 (filterDepartmentTree) | | 2.2 | 상태 필터 추가 (전체/활성/비활성) | ✅ | Select 드롭다운 | | 2.3 | 필터 적용 로직 (index.tsx) | ✅ | filteredDepartments useMemo | ### 2.3 Phase 3: 삭제 & 복원 — ⏭️ 추후 작업 (현재 MNG에서 관리) > **결정**: 삭제/복원은 현재 MNG에서 관리. 추후 React에서 직접 관리 시 진행. > **전제조건**: V1 API에 restore 엔드포인트 추가, tree API에 with_trashed 파라미터 추가 필요. | # | 작업 항목 | 상태 | 비고 | |---|----------|:----:|------| | 3.1 | 삭제 상태 필터 추가 (일반/삭제포함/삭제만) | ⏭️ | API 변경 필요: tree에 with_trashed 파라미터 | | 3.2 | 삭제된 부서 표시 UI (배경색, 뱃지) | ⏭️ | React만 | | 3.3 | 복원 기능 — actions.ts + 복원 버튼 | ⏭️ | API 추가 필요: POST /v1/departments/{id}/restore | | 3.4 | 일괄 복원 | ⏭️ | API 추가 필요 | ### 2.4 Phase 4: 편의 기능 — ⏭️ 추후 작업 | # | 작업 항목 | 상태 | 비고 | |---|----------|:----:|------| | 4.1 | 통계 카드 확장 (활성/비활성 카운트) | ⏭️ | React만, API 불필요 | | 4.2 | 영구삭제 (슈퍼관리자 전용) | ⏭️ | API 추가 필요 | | 4.3 | 부서 이동 (parentId 변경) UI | ⏭️ | API는 이미 지원 (PATCH parent_id) | --- ## 3. 작업 절차 ### 3.1 단계별 절차 ``` Phase 1: 타입 & 폼 필드 보강 (핵심 — 먼저 완료) ├── 1.1 types.ts 확장 │ └── Department 인터페이스에 code, description, isActive, sortOrder 추가 ├── 1.2 actions.ts 수정 │ ├── ApiDepartment → DepartmentRecord 변환에 누락 필드 포함 확인 │ ├── createDepartment, updateDepartment 요청 데이터에 필드 추가 │ └── getDepartmentTree 응답 매핑 확인 ├── 1.3 DepartmentDialog 폼 확장 │ ├── Zod 스키마 정의 (code 필수, name 필수, description 선택, sortOrder 선택, isActive 기본 true) │ ├── 폼 필드 추가 (부서코드, 부서명, 설명, 정렬순서, 활성상태) │ └── 수정 모드 시 기존 값 로드 └── 1.4 DepartmentTreeItem UI 보강 ├── 부서코드 표시 (부서명 옆) └── 활성/비활성 상태 뱃지 Phase 2: 검색 & 필터 ├── 2.1 검색 기능 구현 │ └── 트리 재귀 탐색으로 이름/코드 매칭 필터 ├── 2.2 상태 필터 드롭다운 추가 │ └── DepartmentToolbar에 Select 컴포넌트 추가 └── 2.3 필터 적용 로직 └── index.tsx에 filteredDepartments useMemo Phase 3~4: ⏭️ 추후 작업 (현재 MNG에서 관리, API 변경 필요) ``` --- ## 4. 상세 작업 내용 ### 4.1 Phase 1 상세 #### 1.1 types.ts 확장 ```typescript // 현재 interface Department { id: number; name: string; parentId: number | null; depth: number; children?: Department[]; } // 변경 후 interface Department { id: number; code: string | null; name: string; description: string | null; parentId: number | null; isActive: boolean; sortOrder: number; depth: number; children?: Department[]; deletedAt?: string | null; // Phase 3용 } ``` #### 1.3 DepartmentDialog 폼 — Zod 스키마 ```typescript const departmentFormSchema = z.object({ code: z.string().min(1, '부서 코드를 입력하세요').max(50), name: z.string().min(1, '부서명을 입력하세요').max(100), description: z.string().max(500).optional().or(z.literal('')), sortOrder: z.number().min(0).default(0), isActive: z.boolean().default(true), }); ``` #### 1.4 DepartmentTreeItem UI 예시 ``` [▼] [☑] DEPT001 경영지원본부 [활성] [+] [✎] [🗑] [▼] [☑] HR001 인사팀 [활성] [▶] [☑] FIN001 재무팀 [비활성] ``` ### 4.2 Phase 3 상세 — ⏭️ 추후 작업 시 참고 > 2026-03-13 확인 완료: V1 API에 restore, force-delete, with_trashed 모두 없음. > Phase 3 진행 시 API 변경 필수 (api/ 저장소). **필요한 API 변경:** 1. `POST /v1/departments/{id}/restore` — 라우트 + 컨트롤러 + 서비스 추가 2. `GET /v1/departments/tree?with_trashed=1` — tree()에 withTrashed 스코프 추가 3. Department 모델 `$hidden`에서 `deleted_at` 조건부 노출 --- ## 5. 컨펌 대기 목록 | # | 항목 | 변경 내용 | 영향 범위 | 상태 | |---|------|----------|----------|------| | 1 | Phase 1~2 진행 | React만 수정, API 변경 없음 | react/ | ✅ 승인됨 | | 2 | Phase 3~4 보류 | 추후 MNG→React 이관 시 진행 (API 변경 필요) | api/ + react/ | ⏭️ 보류 | --- ## 6. 변경 이력 | 날짜 | 항목 | 변경 내용 | 파일 | 승인 | |------|------|----------|------|------| | 2026-03-12 | - | 계획 문서 초안 작성 | - | - | --- ## 7. 참고 문서 - **부서 트리 API 규칙**: `docs/rules/department-tree-api.md` - **프론트엔드 API 패턴**: `docs/frontend/v1/02-api-pattern.md` - **프론트엔드 폼 패턴**: `docs/frontend/v1/05-form-pattern.md` - **프론트엔드 컴포넌트 설계**: `docs/frontend/v1/03-component-design.md` - **품질 체크리스트**: `docs/dev/standards/quality-checklist.md` ### 참고 소스 경로 **React (수정 대상):** ``` react/src/components/hr/DepartmentManagement/ ├── index.tsx — 메인 컴포넌트 (상태 관리) ├── types.ts — 타입 정의 + 유틸리티 ├── actions.ts — 서버 액션 (API 호출) ├── DepartmentTree.tsx — 트리 컨테이너 ├── DepartmentTreeItem.tsx — 트리 행 (재귀) ├── DepartmentDialog.tsx — 추가/수정 모달 ├── DepartmentToolbar.tsx — 검색 + 버튼 └── DepartmentStats.tsx — 통계 카드 ``` **MNG (참고용):** ``` mng/app/Http/Controllers/Api/Admin/DepartmentController.php mng/app/Services/DepartmentService.php mng/app/Http/Requests/StoreDepartmentRequest.php mng/app/Http/Requests/UpdateDepartmentRequest.php mng/resources/views/departments/ ``` **API (확인 대상):** ``` api/app/Http/Controllers/Api/V1/DepartmentController.php api/app/Services/DepartmentService.php ``` --- ## 8. 일정 산정 | Phase | 작업량 | 수정 범위 | 비고 | |-------|--------|----------|------| | **Phase 1** | 중간 | React 4개 파일 | API 변경 없음 | | **Phase 2** | 가벼움 | React 2개 파일 | API 변경 없음 | | Phase 3 | 무거움 | API 4개 + React 4개 파일 | ⏭️ 추후 | | Phase 4 | 가벼움 | React 2~3개 파일 | ⏭️ 추후 | **현재 스코프**: Phase 1 → Phase 2 (순차, React만 수정) **수정 대상 파일**: types.ts, actions.ts, DepartmentDialog.tsx, DepartmentTreeItem.tsx, DepartmentToolbar.tsx, index.tsx --- ## 9. 검증 결과 > 작업 완료 후 이 섹션에 검증 결과 추가 ### 9.1 테스트 체크리스트 | 테스트 항목 | 예상 결과 | 실제 결과 | 상태 | |------------|----------|----------|------| | 부서 생성 (전체 필드) | code, name, description, sortOrder, isActive 저장 | | ⏳ | | 부서 수정 (전체 필드) | 모든 필드 수정 반영 | | ⏳ | | 부서 코드 중복 검증 | 에러 메시지 표시 | | ⏳ | | 검색 (이름) | 매칭 부서만 트리에 표시 | | ⏳ | | 검색 (코드) | 매칭 부서만 트리에 표시 | | ⏳ | | 상태 필터 (활성만) | 비활성 부서 숨김 | | ⏳ | | 상태 필터 (비활성만) | 활성 부서 숨김 | | ⏳ | | 삭제된 부서 표시 | 빨간 배경 + "삭제됨" 뱃지 | | ⏳ | | 삭제된 부서 복원 | 정상 복원, 트리 갱신 | | ⏳ | | 트리 펼치기/접기 | 기존 기능 유지 | | ⏳ | | 전체 선택/해제 | 기존 기능 유지 | | ⏳ | ### 9.2 성공 기준 달성 현황 | 기준 | 달성 | 비고 | |------|:----:|------| | MNG CRUD 동일 수준 | ⏳ | | | 전체 필드 폼 포함 | ⏳ | | | 검색/필터 동작 | ⏳ | | | 삭제 부서 복원 가능 | ⏳ | | | 트리 리스트 정보 표시 | ⏳ | | --- ## 10. 자기완결성 점검 결과 ### 10.1 체크리스트 검증 | # | 검증 항목 | 상태 | 비고 | |---|----------|:----:|------| | 1 | 작업 목적이 명확한가? | ✅ | 1.1 배경 | | 2 | 성공 기준이 정의되어 있는가? | ✅ | 1.3 성공 기준 | | 3 | 작업 범위가 구체적인가? | ✅ | 섹션 2 전체 | | 4 | 의존성이 명시되어 있는가? | ✅ | 컨펌 대기 목록 | | 5 | 참고 파일 경로가 정확한가? | ✅ | 섹션 7 | | 6 | 단계별 절차가 실행 가능한가? | ✅ | 섹션 3 | | 7 | 검증 방법이 명시되어 있는가? | ✅ | 섹션 9 | | 8 | 모호한 표현이 없는가? | ✅ | | ### 10.2 새 세션 시뮬레이션 테스트 | 질문 | 답변 가능 | 참조 섹션 | |------|:--------:|----------| | Q1. 이 작업의 목적은 무엇인가? | ✅ | 1.1 배경 | | Q2. 어디서부터 시작해야 하는가? | ✅ | 3.1 단계별 절차 | | Q3. 어떤 파일을 수정해야 하는가? | ✅ | 7. 참고 소스 경로 | | Q4. 작업 완료 확인 방법은? | ✅ | 9. 검증 결과 | | Q5. 막혔을 때 참고 문서는? | ✅ | 7. 참고 문서 | --- *이 문서는 /plan 스킬로 생성되었습니다.*