diff --git a/dev/dev_plans/approval-system-unification-plan.md b/dev/dev_plans/approval-system-unification-plan.md index 38cba14..ce653aa 100644 --- a/dev/dev_plans/approval-system-unification-plan.md +++ b/dev/dev_plans/approval-system-unification-plan.md @@ -1,7 +1,7 @@ # 결재관리 시스템 통합 계획서 — MNG 로직을 API로 통합 > **작성일**: 2026-03-11 -> **상태**: 설계 중 +> **상태**: P1~P4 완료 / P5~P6 미착수 > **담당**: R&D실 > **관련 문서**: [`phase4-approval-integration-plan.md`](./phase4-approval-integration-plan.md) (Document↔Approval 브릿지, 완료) @@ -11,21 +11,21 @@ ### 1.1 배경 -현재 SAM의 결재관리 시스템이 MNG와 API에 **이중 구현**되어 있다. +MNG와 API에 이중 구현되어 있던 결재관리 시스템을 API로 통합하는 작업이다. **P1~P4는 완료되어 API가 MNG와 동등한 기능을 제공**한다. -| 항목 | MNG (관리자 패널) | API (REST API) | -|------|------------------|----------------| -| 결재 흐름 | 상신/승인/반려/회수/**보류/전결/복사재기안** | 상신/승인/반려/회수 | -| 위임 시스템 | ✅ 완전 구현 | ❌ 미구현 | -| 병렬 결재 | ✅ `parallel_group` | ❌ 미구현 | -| 결재자 스냅샷 | ✅ 이름/부서/직급 | ❌ 미구현 | -| 대결 처리 | ✅ `acted_by` | ❌ 미구현 | -| 반려 이력 | ✅ `rejection_history` | ❌ 미구현 | -| 뱃지 카운트 | ✅ 4종 뱃지 | ❌ 미구현 | -| 양식별 뷰 | ✅ 27개 Blade 파일 | ❌ (React 측 담당) | -| Leave 연동 | ✅ 결재 완료→휴가 자동 생성 | ❌ 미구현 | -| Document 동기화 | ❌ | ✅ `syncToLinkedDocument()` | -| 현황 요약 API | ❌ | ✅ `draftsSummary()`, `inboxSummary()` | +| 항목 | MNG (관리자 패널) | API (REST API) | 비고 | +|------|------------------|----------------|------| +| 결재 흐름 | ✅ 상신/승인/반려/회수/보류/전결/복사재기안 | ✅ 동일 | P2에서 완료 | +| 위임 시스템 | ✅ 완전 구현 | ✅ CRUD 구현 | P4에서 완료 | +| 병렬 결재 | ✅ `parallel_group` | ⚠️ 컬럼 존재, 로직 미확인 | 검증 필요 | +| 결재자 스냅샷 | ✅ 이름/부서/직급 | ✅ 구현 완료 | P2에서 완료 | +| 대결 처리 | ✅ `acted_by` | ⚠️ 컬럼 존재, 위임 inbox 통합 미확인 | 검증 필요 | +| 반려 이력 | ✅ `rejection_history` | ✅ 구현 완료 | P2에서 완료 | +| 뱃지 카운트 | ✅ 4종 뱃지 | ✅ 구현 완료 | P2에서 완료 | +| 양식별 뷰 | ✅ 27개 Blade 파일 | ❌ (React 측 담당) | 범위 외 | +| Leave 연동 | ✅ 결재 완료→휴가 자동 생성 | ❌ 미구현 | **P5 미착수** | +| Document 동기화 | ❌ | ✅ `syncToLinkedDocument()` | API 고유 | +| 현황 요약 API | ❌ | ✅ `draftsSummary()`, `inboxSummary()` | API 고유 | MNG에서 코드브릿지엑스(tenant_id=1)만 사용하던 결재 시스템을 **모든 테넌트가 API를 통해 동일하게 사용**할 수 있도록 통합한다. @@ -49,63 +49,58 @@ MNG에서 코드브릿지엑스(tenant_id=1)만 사용하던 결재 시스템을 --- -## 2. 현재 상태 분석 +## 2. 현재 상태 (2026-03-11 기준) -### 2.1 DB 테이블 현황 +### 2.1 구현 현황 요약 -모든 테이블은 API 마이그레이션으로 이미 생성되어 있다. MNG 모델이 사용하는 컬럼은 DB에 존재하지만, **API 모델에서 활용하지 않는** 상태이다. +| 항목 | 수량 | 상태 | +|------|------|------| +| API 라우트 | 45개 | ✅ 전체 등록 완료 | +| ApprovalController 메서드 | 24개 | ✅ 전체 구현 | +| ApprovalService public 메서드 | 48개 | ✅ 전체 구현 | +| FormRequest 클래스 | 6개 (Approval) + 2개 (Delegation) | ✅ 생성 완료 | +| TODO/FIXME 잔존 | 0건 | ✅ | -| 테이블 | 핵심 컬럼 | DB 존재 | API 모델 활용 | MNG 모델 활용 | -|--------|----------|:-------:|:------------:|:------------:| -| `approvals` | `line_id` | ✅ | ❌ | ✅ | -| | `body` | ✅ | ❌ | ✅ | -| | `is_urgent` | ✅ | ❌ | ✅ | -| | `department_id` | ✅ | ❌ | ✅ | -| | `drafter_read_at` | ✅ | ❌ | ✅ | -| | `resubmit_count` | ✅ | ❌ | ✅ | -| | `rejection_history` | ✅ | ❌ | ✅ | -| | `recall_reason` | ✅ | ❌ | ✅ | -| | `parent_doc_id` | ✅ | ❌ | ✅ | +### 2.2 DB 테이블 현황 + +모든 테이블은 API 마이그레이션으로 생성 완료. API 모델에서도 활용한다. + +| 테이블 | 핵심 컬럼 | DB 존재 | API 활용 | MNG 활용 | +|--------|----------|:-------:|:-------:|:-------:| +| `approvals` | `line_id`, `body`, `is_urgent`, `department_id` | ✅ | ✅ | ✅ | +| | `drafter_read_at`, `resubmit_count`, `rejection_history` | ✅ | ✅ | ✅ | +| | `recall_reason`, `parent_doc_id` | ✅ | ✅ | ✅ | | | `linkable_type/id` | ✅ | ✅ | ❌ | -| `approval_steps` | `parallel_group` | ✅ | ❌ | ✅ | -| | `acted_by` | ✅ | ❌ | ✅ | -| | `approver_name` | ✅ | ❌ | ✅ | -| | `approver_department` | ✅ | ❌ | ✅ | -| | `approver_position` | ✅ | ❌ | ✅ | -| | `approval_type` | ✅ | ❌ | ✅ | -| `approval_forms` | `body_template` | ✅ | ❌ | ✅ | -| `approval_delegations` | 전체 | ✅ | ❌ | ✅ | +| `approval_steps` | `tenant_id`, `deleted_at` | ✅ | ✅ | ✅ | +| | `parallel_group`, `acted_by` | ✅ | ⚠️ | ✅ | +| | `approver_name/department/position` | ✅ | ✅ | ✅ | +| | `approval_type` | ✅ | ✅ | ✅ | +| `approval_forms` | `body_template` | ✅ | ✅ | ✅ | +| `approval_delegations` | 전체 | ✅ | ✅ | ✅ | -> **핵심**: DB 스키마 변경이 거의 불필요하다. API 모델과 서비스만 확장하면 된다. +> **2026-03-11 추가 마이그레이션**: `approval_steps` 테이블에 `tenant_id` + `deleted_at` 컬럼 추가 (`BelongsToTenant`, `SoftDeletes` 적용) -### 2.2 API 모델 vs MNG 모델 상태 비교 +### 2.3 API 서비스 기능 현황 -| API 모델 (현재) | MNG 모델 (목표) | 차이 | -|----------------|----------------|------| -| `STATUS_CANCELLED` 까지 | `STATUS_ON_HOLD` 추가 | 상태 1개 추가 | -| `isEditable()`, `isActionable()`, `isCancellable()`, `isDeletable()` | + `isHoldable()`, `isHoldReleasable()`, `isCopyable()`, `isDeletableBy(user)` | 메서드 4개 추가 | -| `steps()`, `approverSteps()`, `referenceSteps()` | + `parentDocument()`, `childDocuments()` | 관계 2개 추가 | -| — | `getStatusColorAttribute()` | Accessor 1개 추가 | - -### 2.3 API 서비스 vs MNG 서비스 기능 비교 - -| 기능 | API | MNG | 이식 필요 | -|------|:---:|:---:|:---------:| -| 기안함/결재함/참조함 조회 | ✅ | ✅ | — | -| 문서 CRUD | ✅ | ✅ | — | -| 상신/승인/반려/회수 | ✅ | ✅ | — | -| **보류 (hold)** | ❌ | ✅ | ✅ | -| **보류 해제 (releaseHold)** | ❌ | ✅ | ✅ | -| **전결 (preDecide)** | ❌ | ✅ | ✅ | -| **복사 재기안 (copyForRedraft)** | ❌ | ✅ | ✅ | -| **뱃지 카운트 (badgeCounts)** | ❌ | ✅ | ✅ | -| **완료함 일괄 읽음** | ❌ | ✅ | ✅ | -| **결재자 스냅샷 저장** | ❌ | ✅ | ✅ | -| **반려 후 재상신 이력** | ❌ | ✅ | ✅ | -| **Leave 연동** | ❌ | ✅ | ✅ | -| 현황 요약 (summary) | ✅ | ❌ | — (유지) | -| 참조 미열람 (markUnread) | ✅ | ❌ | — (유지) | -| Document 동기화 | ✅ | ❌ | — (유지) | +| 기능 | API | MNG | 상태 | +|------|:---:|:---:|:----:| +| 기안함/결재함/참조함/완료함 조회 | ✅ | ✅ | 완료 | +| 문서 CRUD | ✅ | ✅ | 완료 | +| 상신/승인/반려/회수 | ✅ | ✅ | 완료 | +| 보류 / 보류 해제 | ✅ | ✅ | 완료 | +| 전결 (preDecide) | ✅ | ✅ | 완료 | +| 복사 재기안 (copyForRedraft) | ✅ | ✅ | 완료 | +| 뱃지 카운트 (badgeCounts) | ✅ | ✅ | 완료 | +| 완료함 일괄 읽음 | ✅ | ✅ | 완료 | +| 결재자 스냅샷 저장 | ✅ | ✅ | 완료 | +| 반려 후 재상신 이력 | ✅ | ✅ | 완료 | +| 위임 CRUD | ✅ | ✅ | 완료 | +| 현황 요약 (summary) | ✅ | ❌ | API 고유 | +| 참조 미열람 (markUnread) | ✅ | ❌ | API 고유 | +| Document 동기화 | ✅ | ❌ | API 고유 | +| **병렬 결재 (parallel_group)** | ⚠️ | ✅ | **검증 필요** | +| **위임 inbox 통합 (대결 처리)** | ⚠️ | ✅ | **검증 필요** | +| **Leave 연동** | ❌ | ✅ | **P5 미착수** | --- @@ -113,18 +108,18 @@ MNG에서 코드브릿지엑스(tenant_id=1)만 사용하던 결재 시스템을 ### 3.1 전체 단계 요약 -| Phase | 작업 | 예상 규모 | 영향 범위 | -|:-----:|------|----------|----------| -| **P1** | API 모델 확장 | 중간 | API 모델 4개 수정 | -| **P2** | API 서비스 — 핵심 워크플로우 이식 | 대규모 | ApprovalService 확장 | -| **P3** | API 엔드포인트 추가 | 중간 | 컨트롤러/라우트/FormRequest | -| **P4** | 위임(Delegation) 시스템 이식 | 중간 | 모델+서비스+컨트롤러 신규 | -| **P5** | Leave 연동 이식 | 소규모 | 서비스 로직 추가 | -| **P6** | 테스트 및 검증 | 중간 | 전체 | +| Phase | 작업 | 상태 | 비고 | +|:-----:|------|:----:|------| +| **P1** | API 모델 확장 | ✅ 완료 | 모델 4개 수정/생성, ApprovalStep에 tenant_id+SoftDeletes 추가 | +| **P2** | API 서비스 — 핵심 워크플로우 이식 | ✅ 완료 | 48개 public 메서드 구현 | +| **P3** | API 엔드포인트 추가 | ✅ 완료 | 45개 라우트, 24개 컨트롤러 메서드, FormRequest 6개 | +| **P4** | 위임(Delegation) 시스템 이식 | ✅ 완료 | CRUD 구현, FormRequest 2개 | +| **P5** | Leave 연동 이식 | ❌ 미착수 | 결재 완료→휴가 자동 생성 | +| **P6** | 테스트 및 검증 | ❌ 미착수 | 병렬 결재, 위임 inbox 통합 검증 포함 | --- -## 4. Phase 1 — API 모델 확장 +## 4. Phase 1 — API 모델 확장 ✅ 완료 ### 4.1 Approval 모델 (`api/app/Models/Tenants/Approval.php`) @@ -270,7 +265,7 @@ MNG의 `ApprovalDelegation` 모델을 API에 생성한다. --- -## 5. Phase 2 — API 서비스 핵심 워크플로우 이식 +## 5. Phase 2 — API 서비스 핵심 워크플로우 이식 ✅ 완료 ### 5.1 보류 / 보류 해제 @@ -432,7 +427,7 @@ public function cancel(int $id, ?string $reason = null): Approval --- -## 6. Phase 3 — API 엔드포인트 추가 +## 6. Phase 3 — API 엔드포인트 추가 ✅ 완료 ### 6.1 신규 엔드포인트 목록 @@ -475,7 +470,7 @@ public function cancel(int $id, ?string $reason = null): Approval --- -## 7. Phase 4 — 위임(Delegation) 시스템 이식 +## 7. Phase 4 — 위임(Delegation) 시스템 이식 ✅ 완료 ### 7.1 개요 @@ -514,7 +509,7 @@ inbox 조회 흐름: --- -## 8. Phase 5 — Leave 연동 이식 +## 8. Phase 5 — Leave 연동 이식 ❌ 미착수 ### 8.1 개요 @@ -542,7 +537,7 @@ MNG에서는 휴가 신청 결재가 완료되면 자동으로 Leave 레코드 --- -## 9. Phase 6 — 테스트 및 검증 +## 9. Phase 6 — 테스트 및 검증 ❌ 미착수 ### 9.1 테스트 시나리오 @@ -568,55 +563,68 @@ MNG에서는 휴가 신청 결재가 완료되면 자동으로 Leave 레코드 --- -## 10. 전체 수정 파일 요약 +## 10. 완료된 작업 요약 -### 10.1 API 프로젝트 (`/home/aweso/sam/api`) +### 10.1 API 프로젝트 (`/home/aweso/sam/api`) — P1~P4 완료 -| 파일 | Phase | 유형 | 작업 내용 | -|------|:-----:|------|----------| -| `app/Models/Tenants/Approval.php` | P1 | 수정 | 상수/fillable/cast/관계/메서드 추가 | -| `app/Models/Tenants/ApprovalStep.php` | P1 | 수정 | 상수/fillable/관계 추가 | -| `app/Models/Tenants/ApprovalForm.php` | P1 | 수정 | fillable 추가 | -| `app/Models/Tenants/ApprovalDelegation.php` | P1 | **신규** | 위임 모델 | -| `app/Services/ApprovalService.php` | P2 | 수정 | 6개 메서드 추가 + 기존 메서드 확장 | -| `app/Services/ApprovalDelegationService.php` | P4 | **신규** | 위임 서비스 | -| `app/Http/Controllers/Api/V1/ApprovalController.php` | P3 | 수정 | 6개 액션 메서드 추가 | -| `app/Http/Controllers/Api/V1/ApprovalDelegationController.php` | P4 | **신규** | 위임 컨트롤러 | -| `routes/api/v1/hr.php` | P3,P4 | 수정 | 13개 라우트 추가 | -| `app/Http/Requests/V1/Approval/HoldRequest.php` | P3 | **신규** | | -| `app/Http/Requests/V1/Approval/PreDecideRequest.php` | P3 | **신규** | | -| `app/Http/Requests/V1/Approval/CancelRequest.php` | P3 | 수정 | | -| `app/Http/Requests/V1/ApprovalDelegation/*.php` | P4 | **신규** | 3개 | +| 파일 | Phase | 상태 | 작업 내용 | +|------|:-----:|:----:|----------| +| `app/Models/Tenants/Approval.php` | P1 | ✅ | 상수/fillable/cast/관계/메서드 추가 | +| `app/Models/Tenants/ApprovalStep.php` | P1 | ✅ | BelongsToTenant, SoftDeletes, tenant_id 추가 | +| `app/Models/Tenants/ApprovalForm.php` | P1 | ✅ | ModelTrait 추가, fillable 확장 | +| `app/Models/Tenants/ApprovalDelegation.php` | P1 | ✅ | Auditable, ModelTrait 추가 | +| `app/Services/ApprovalService.php` | P2 | ✅ | 48개 public 메서드 (tenant_id 스냅샷 포함) | +| `app/Http/Controllers/Api/V1/ApprovalController.php` | P3 | ✅ | 24개 메서드, FormRequest 적용 | +| `routes/api/v1/hr.php` | P3,P4 | ✅ | 45개 라우트 등록 | +| `app/Http/Requests/Approval/*.php` | P3 | ✅ | 6개 (Approve, Cancel, Hold, PreDecide, DelegationStore, DelegationUpdate) | +| `database/migrations/2026_03_11_*` | - | ✅ | approval_steps에 tenant_id + deleted_at 추가 | -### 10.2 MNG 프로젝트 (`/home/aweso/sam/mng`) +### 10.2 MNG 프로젝트 (`/home/aweso/sam/mng`) — 최소 수정 -> **MNG는 수정하지 않는다.** 기존 MNG 결재 시스템은 자체 서비스/컨트롤러로 독립 동작하며, 이번 작업의 대상이 아니다. +| 파일 | 작업 | 상태 | +|------|------|:----:| +| `app/Models/Approvals/ApprovalStep.php` | SoftDeletes, tenant_id 추가 | ✅ | +| `app/Services/ApprovalService.php` | tenant_id 스냅샷 로직 추가 | ✅ | ### 10.3 DB 마이그레이션 -> **마이그레이션 불필요.** 모든 필요 컬럼이 이미 API 마이그레이션으로 생성되어 있다. `approval_delegations` 테이블도 이미 존재한다. +| 마이그레이션 | 대상 | 상태 | +|------------|------|:----:| +| `2026_03_11_100001_add_tenant_id_and_soft_deletes_to_approval_steps_table` | `approval_steps` | ✅ 개발/운영 배포 완료 | + +### 10.4 문서 + +| 문서 | 경로 | 상태 | +|------|------|:----:| +| 프론트엔드 API 명세서 | `frontend/api-specs/approval-api.md` | ✅ 작성 완료 | --- ## 11. 작업 순서 및 의존성 ``` -Phase 1: 모델 확장 (독립, 선행 필수) +Phase 1: 모델 확장 ✅ 완료 │ - ├──→ Phase 2: 서비스 워크플로우 (P1 완료 후) + ├──→ Phase 2: 서비스 워크플로우 ✅ 완료 │ │ - │ └──→ Phase 3: 엔드포인트 추가 (P2 완료 후) + │ └──→ Phase 3: 엔드포인트 추가 ✅ 완료 │ - ├──→ Phase 4: 위임 시스템 (P1 완료 후, P2와 병렬 가능) - │ │ - │ └──→ Phase 2에 inbox 위임 통합 (P4 완료 후) + ├──→ Phase 4: 위임 시스템 ✅ 완료 │ - └──→ Phase 5: Leave 연동 (P2 완료 후) + └──→ Phase 5: Leave 연동 ❌ 미착수 (P2 완료 후 가능) │ - └──→ Phase 6: 테스트 (전체 완료 후) + └──→ Phase 6: 테스트 ❌ 미착수 (전체 완료 후) ``` -**권장 실행 순서**: P1 → P2 → P3 → P4 → P5 → P6 +**남은 작업**: P5 (Leave 연동) → P6 (테스트 및 검증) + +### 11.1 추가 검증 필요 항목 + +| 항목 | 설명 | 우선순위 | +|------|------|:--------:| +| 병렬 결재 | `parallel_group` 기반 동시 결재 로직이 API에서 동작하는지 검증 | 중간 | +| 위임 inbox 통합 | inbox 조회 시 위임 대상 문서가 함께 조회되는지 검증 | 중간 | +| 대결 처리 | 대리 결재 시 `acted_by`, `approval_type='delegated'` 기록 여부 | 중간 | --- @@ -648,6 +656,7 @@ Phase 1: 모델 확장 (독립, 선행 필수) | 문서 | 경로 | 설명 | |------|------|------| +| 프론트엔드 API 명세서 | `frontend/api-specs/approval-api.md` | 28개 엔드포인트 전체 명세 | | Document↔Approval 브릿지 | `dev/dev_plans/phase4-approval-integration-plan.md` | 완료된 Phase 4.2 작업 | | DB 스키마 (HR) | `system/database/hr.md` | 인사 관련 테이블 구조 | | DB 스키마 (문서) | `system/database/documents.md` | 문서/전자서명 테이블 구조 |