docs: [approval] MNG↔API 비교 분석 및 React 구현 가이드 추가

- MNG 결재관리 개발 히스토리 (7단계, ~90커밋)
- MNG vs API 기능 비교 매트릭스
- API 반영 현황 및 미반영 항목 정리
- React 구현 시 참조 파일 가이드
- 구현 우선순위 Phase A~D 제안
This commit is contained in:
김보곤
2026-03-11 21:12:26 +09:00
parent 1eaf6564e5
commit 26bd2e024a
3 changed files with 347 additions and 0 deletions

View File

@@ -147,6 +147,8 @@ DB 도메인별:
| [settlement/README.md](features/settlement/README.md) | 정산 |
| [barobill-kakaotalk/README.md](features/barobill-kakaotalk/README.md) | 바로빌 카카오톡 |
| [quality-management/README.md](features/quality-management/README.md) | 품질관리 (제품검사, 실적신고) |
| [approvals/README.md](features/approvals/README.md) | 결재관리 시스템 |
| [approvals/mng-api-comparison.md](features/approvals/mng-api-comparison.md) | 결재관리 MNG↔API 비교 분석 및 React 구현 가이드 |
---

View File

@@ -23,6 +23,7 @@ SAM MNG 전자결재 시스템. 기안부터 최종 승인, 반려, 회수, 보
| [api-reference.md](api-reference.md) | API 엔드포인트 명세 |
| [ui-screens.md](ui-screens.md) | 화면별 UI 구성 및 동작 |
| [db-changes-and-model-sync.md](db-changes-and-model-sync.md) | DB 변경사항 및 API/MNG 모델 동기화 현황 |
| [mng-api-comparison.md](mng-api-comparison.md) | MNG↔API 비교 분석 및 React 구현 가이드 |
### 1.3 구현 현황

View File

@@ -0,0 +1,344 @@
# 결재관리 MNG↔API 비교 분석 및 반영 가이드
> **작성일**: 2026-03-11
> **상태**: 분석 완료
> **목적**: React 결재관리 화면 구현 시 참고 자료
---
## 1. 개요
### 1.1 배경
결재관리는 API(2025-12-17)에서 최초 구현되었고, MNG(2026-02-27)가 이를 참조하여 구축했다. MNG가 실제 관리자 화면을 만들면서 ~90개 커밋에 걸쳐 대폭 진화했으며, API는 2026-03-11에 "MNG 스타일로 전면 개선" 커밋으로 역반영을 시작했다.
### 1.2 핵심 사실
- MNG와 API는 **동일한 5개 테이블**을 공유한다 (`approvals`, `approval_steps`, `approval_lines`, `approval_forms`, `approval_delegations`)
- 마이그레이션은 **API에서만** 관리한다 (24개 마이그레이션)
- MNG 모델은 API 모델의 **수동 동기 사본**이다
---
## 2. 개발 타임라인
```
2025-12-17 API 최초 구현 (기본 CRUD + 워크플로우 4종)
▼ ─── 약 2개월간 API만 단독 운영 ───
2026-02-27 MNG Phase 1 MVP (API 참조하여 구축, 19파일 2806줄)
2026-02-27 MNG Phase 2 고급기능 (보류/전결/복사재기안, 10파일 757줄)
▼ ─── MNG 독자 진화 시작 ───
2026-02-28 결재선 UI/UX 대폭 개선 (~12 커밋)
- Alpine.js v3 호환, 2패널 에디터, Toss 스타일
- 결재선 템플릿 CRUD, 드래그앤드롭, 모달 전환
- 기본 결재선 자동 선택, Quill.js 편집기
2026-02-28 휴가신청 → 전자결재 자동연동
2026-03-03 삭제 권한 기능 (isDeletableBy, 관리자 삭제)
2026-03-04 지출결의서 전용 폼 (첨부파일 GCS, 법인카드/송금 선택)
2026-03-05 반려이력/재상신, 결재서명란, 거래처 검색, 불러오기
2026-03-05 증명서류 양식 (재직/경력/위촉증명서, 사직서) + PDF
2026-03-06 업무양식 (품의서5종, 인감/위임장/의사록/견적서/공문서)
2026-03-07 연차촉진통지서, 결재/참조선 2영역 분리
▼ ─── MNG 실무 검증 완료 ───
2026-03-11 API "MNG 스타일로 전면 개선" (역방향 반영)
```
---
## 3. 공유 테이블 (5개)
| 테이블 | MNG 모델 경로 | API 모델 경로 |
|--------|-------------|-------------|
| `approvals` | `mng/app/Models/Approvals/Approval.php` | `api/app/Models/Tenants/Approval.php` |
| `approval_steps` | `mng/app/Models/Approvals/ApprovalStep.php` | `api/app/Models/Tenants/ApprovalStep.php` |
| `approval_lines` | `mng/app/Models/Approvals/ApprovalLine.php` | `api/app/Models/Tenants/ApprovalLine.php` |
| `approval_forms` | `mng/app/Models/Approvals/ApprovalForm.php` | `api/app/Models/Tenants/ApprovalForm.php` |
| `approval_delegations` | `mng/app/Models/Approvals/ApprovalDelegation.php` | `api/app/Models/Tenants/ApprovalDelegation.php` |
> MNG에만 있는 별도 테이블: `document_approvals`, `document_template_approval_lines` (문서관리 전용, 메인 결재관리와 무관)
---
## 4. MNG vs API 기능 비교
### 4.1 MNG에서 추가/개선된 기능 (API 원본에 없던 것)
| 분류 | MNG 기능 | 설명 | API 반영 상태 |
|------|----------|------|-------------|
| **워크플로우** | 보류/해제 | `hold()`, `releaseHold()` | ✅ 반영됨 |
| **워크플로우** | 전결 | `preDecide()` — 이후 단계 건너뜀 | ✅ 반영됨 |
| **워크플로우** | 복사재기안 | `copyForRedraft()` — 완료/반려/회수 문서 복사 | ✅ 반영됨 |
| **재상신** | `resubmit_count`, `rejection_history` | 반려 이력 JSON, 재상신 횟수 추적 | ✅ 반영됨 |
| **결재선 UI** | 2패널 에디터 | 좌: 조직도, 우: 선택된 결재선 | ❌ React 구현 필요 |
| **결재선 UI** | 드래그앤드롭 | 결재 순서 변경 | ❌ React 구현 필요 |
| **결재선 UI** | 결재/참조 2영역 분리 | 결재선과 참조선 별도 관리 | ❌ React 구현 필요 |
| **결재선 UI** | Toss 스타일 모달 | 결재선 관리 모달 | ❌ React 구현 필요 |
| **양식 시스템** | 2단계 선택 | 분류 → 양식 드릴다운 | ❌ React 구현 필요 |
| **양식 시스템** | 본문 자동채움 | `body_template` 기반 자동 렌더링 | ❌ React 구현 필요 |
| **양식 시스템** | Quill.js 편집기 | 리치텍스트 본문 편집 토글 | ❌ React 구현 필요 |
| **전용 양식 15종** | 지출결의서 외 다수 | 아래 4.2 참조 | ❌ React 구현 필요 |
| **지출결의서** | 법인카드/송금 선택 | 지출형식별 동적 UI | ❌ React 구현 필요 |
| **지출결의서** | 첨부파일 업로드 | GCS 연동 | ❌ API 엔드포인트 필요 |
| **지출결의서** | 거래처 검색 | 업체명 자동완성 | ❌ React 구현 필요 |
| **지출결의서** | 불러오기 | 이전 결의서 복사 | ❌ React 구현 필요 |
| **결재서명란** | 전통 도장식 테이블 | `_approval-stamp-table.blade.php` | ❌ React 구현 필요 |
| **증명서 PDF** | 4종 PDF 다운로드 | 재직/경력/위촉증명서, 사직서 | ❌ API PDF 엔드포인트 필요 |
| **삭제 권한** | `isDeletableBy()` | 관리자/슈퍼관리자 강제삭제, 일괄삭제 | ❌ API 엔드포인트 필요 |
| **뱃지** | 진행중 건수 | 기안함 뱃지 = 진행중 문서 수 | ✅ badge-counts 반영 |
| **완료함** | 미읽음 알림 | `drafter_read_at` 기반 | ✅ 반영됨 |
| **휴가 연동** | 결재→Leave 자동 변경 | 승인/반려/회수 시 Leave 상태 동기화 | ✅ 반영됨 |
### 4.2 MNG 전용 양식 목록 (15종+)
| 카테고리 | 양식명 | MNG Blade 파일 | PDF |
|---------|--------|---------------|-----|
| **근태** | 연차/반차/조퇴 신청 | `_leave-form.blade.php` | — |
| **지출** | 지출결의서 | `_expense-form.blade.php` | — |
| **품의** | 지출품의서 | `_purchase-request-form.blade.php` | — |
| **품의** | 계약체결품의서 | 상동 (5종 분기) | — |
| **품의** | 구매품의서 | 상동 | — |
| **품의** | 출장품의서 | 상동 | — |
| **품의** | 비용정산서 | 상동 | — |
| **증명** | 재직증명서 | `_certificate-form.blade.php` | ✅ |
| **증명** | 경력증명서 | `_career-cert-form.blade.php` | ✅ |
| **증명** | 위촉증명서 | `_appointment-cert-form.blade.php` | ✅ |
| **인사** | 사직서 | `_resignation-form.blade.php` | ✅ |
| **업무** | 사용인감계 | `_seal-usage-form.blade.php` | — |
| **업무** | 위임장 | `_delegation-form.blade.php` | — |
| **업무** | 이사회의사록 | `_board-minutes-form.blade.php` | — |
| **업무** | 견적서 | `_quotation-form.blade.php` | — |
| **업무** | 공문서 | `_official-letter-form.blade.php` | — |
| **근태** | 연차촉진통지서 1차 | `_leave-promotion-1st-form.blade.php` | — |
| **근태** | 연차촉진통지서 2차 | `_leave-promotion-2nd-form.blade.php` | — |
> 각 양식은 `_<name>-form.blade.php` (기안 작성)와 `_<name>-show.blade.php` (상세 조회) 쌍으로 구성
---
## 5. API 반영 현황
### 5.1 이미 반영 완료
| 항목 | 설명 |
|------|------|
| DB 스키마 | 마이그레이션 24개 — MNG와 완전 동기화 |
| 모델 상수/관계/헬퍼 | 6가지 문서 상태, 5가지 단계 상태, 3가지 step_type |
| 워크플로우 전체 | submit/approve/reject/cancel/hold/releaseHold/preDecide/copyForRedraft |
| 위임 CRUD | delegations 엔드포인트 4개 |
| 결재함 4종 + badge-counts | drafts/inbox/reference/completed + summary |
| FormRequest 검증 21개 | MNG보다 정교하게 분리 |
| Swagger 문서 | 3개 파일 (ApprovalApi, ApprovalFormApi, ApprovalLineApi) |
| Leave/Document 연동 | 결재 상태 변경 시 연관 엔티티 자동 동기화 |
| Observer 알림 | TodayIssue 발행 (ApprovalIssueObserver, ApprovalStepIssueObserver) |
| 테넌트 부트스트랩 | 새 테넌트 생성 시 기본 양식 5종 자동 시딩 |
### 5.2 API에 미반영 (React 화면 개발 시 필요)
| 항목 | 설명 | 난이도 | 비고 |
|------|------|--------|------|
| 🔴 전용 양식 렌더링 | 15종 양식별 폼 UI + 조회 UI | 대형 | MNG Blade를 React로 재구현 |
| 🔴 결재선 에디터 UI | 2패널 + 드래그앤드롭 + 결재/참조 분리 | 대형 | MNG의 `_approval-line-editor.blade.php` 참조 |
| 🟡 결재서명란 | 전통 도장식 결재 테이블 | 중형 | MNG의 `_approval-stamp-table.blade.php` 참조 |
| 🟡 양식 2단계 선택 | 분류 → 양식 드릴다운 | 중형 | |
| 🟡 증명서 PDF 출력 | API에서 DomPDF 렌더링 엔드포인트 | 중형 | MNG는 자체 처리 중 |
| 🟡 위임 결재 실제 동작 | `acted_by` 대결 처리 로직 | 중형 | Phase 3 |
| 🟡 병렬 결재 | `parallel_group` 활용 로직 | 중형 | Phase 3 |
| 🟢 첨부파일 업로드 | 결재 전용 업로드/다운로드 엔드포인트 | 소형 | 공통 File API 활용 가능 |
| 🟢 관리자 강제삭제 | 슈퍼관리자 권한 관리/일괄삭제 | 소형 | |
| 🟢 결재 통계/리포트 | 기간별/부서별/양식별 통계 | 소형 | Phase 4 |
---
## 6. 프로젝트별 역할 분담
```
MNG (관리자 화면 - Blade) API (REST 백엔드) React (사용자 화면)
┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
│ ✅ 결재 전체 기능 │ │ ✅ 워크플로우 로직 │ │ ❌ 화면 미구현 │
│ ✅ 15종+ 양식 UI │ │ ✅ REST API 전체 │ │ │
│ ✅ 결재선 에디터 │ │ ✅ FormRequest 검증 │ │ React에서 구현 필요: │
│ ✅ 결재서명란 │ │ ✅ Swagger 문서 │ │ - 양식별 폼 UI │
│ ✅ PDF 출력 4종 │ │ ✅ Observer 알림 │ │ - 결재선 에디터 │
│ ✅ 첨부파일 GCS │ │ ✅ Leave/Doc 연동 │ │ - 결재서명란 │
│ ✅ 관리자 강제삭제 │ │ ✅ 테넌트 부트스트랩 │ │ - PDF 다운로드 │
│ ✅ 일괄삭제 │ │ │ │ - 파일 업로드 │
│ │ │ ❌ PDF 생성 엔드포인트│ │ │
│ │ │ ❌ 위임 대결 로직 │ │ │
│ │ │ ❌ 병렬 결재 로직 │ │ │
└──────────────────────┘ └──────────────────────┘ └──────────────────────┘
가장 완성도 높음 백엔드 로직 완성 UI 구현 대기 중
```
---
## 7. React 구현 시 MNG 참조 파일 가이드
### 7.1 뷰 파일 구조 (`mng/resources/views/approvals/`)
```
approvals/
├── drafts.blade.php ← 기안함 목록
├── pending.blade.php ← 결재 대기함 목록
├── completed.blade.php ← 처리 완료함 목록
├── references.blade.php ← 참조함 목록
├── create.blade.php ← 기안 작성
├── edit.blade.php ← 기안 수정
├── show.blade.php ← 결재 상세 조회
├── partials/
│ ├── _approval-line-editor.blade.php ← 🔴 결재선 에디터 (핵심 UI)
│ ├── _approval-stamp-table.blade.php ← 🟡 결재서명란
│ ├── _status-badge.blade.php ← 상태 뱃지
│ ├── _step-progress.blade.php ← 결재 진행 현황
│ │
│ ├── _expense-form.blade.php ← 지출결의서 기안
│ ├── _expense-show.blade.php ← 지출결의서 조회
│ ├── _certificate-form.blade.php ← 재직증명서 기안
│ ├── _certificate-show.blade.php ← 재직증명서 조회
│ ├── _career-cert-form.blade.php ← 경력증명서 기안
│ ├── _career-cert-show.blade.php ← 경력증명서 조회
│ ├── _appointment-cert-form.blade.php ← 위촉증명서 기안
│ ├── _appointment-cert-show.blade.php ← 위촉증명서 조회
│ ├── _resignation-form.blade.php ← 사직서 기안
│ ├── _resignation-show.blade.php ← 사직서 조회
│ ├── _purchase-request-form.blade.php ← 품의서 기안 (5종)
│ ├── _purchase-request-show.blade.php ← 품의서 조회
│ ├── _seal-usage-form.blade.php ← 인감 기안
│ ├── _seal-usage-show.blade.php ← 인감 조회
│ ├── _delegation-form.blade.php ← 위임장 기안
│ ├── _delegation-show.blade.php ← 위임장 조회
│ ├── _board-minutes-form.blade.php ← 의사록 기안
│ ├── _board-minutes-show.blade.php ← 의사록 조회
│ ├── _quotation-form.blade.php ← 견적서 기안
│ ├── _quotation-show.blade.php ← 견적서 조회
│ ├── _official-letter-form.blade.php ← 공문서 기안
│ ├── _official-letter-show.blade.php ← 공문서 조회
│ ├── _leave-form.blade.php ← 근태신청 기안
│ ├── _leave-show.blade.php ← 근태신청 조회
│ ├── _leave-promotion-1st-form.blade.php ← 연차촉진 1차
│ ├── _leave-promotion-1st-show.blade.php
│ ├── _leave-promotion-2nd-form.blade.php ← 연차촉진 2차
│ └── _leave-promotion-2nd-show.blade.php
```
### 7.2 API 엔드포인트 참조
| MNG 엔드포인트 (내부 API) | 대응하는 API 엔드포인트 |
|--------------------------|----------------------|
| `POST /api/v1/approval-mgmt` | `POST /v1/approvals` |
| `GET /api/v1/approval-mgmt/{id}` | `GET /v1/approvals/{id}` |
| `PUT /api/v1/approval-mgmt/{id}` | `PATCH /v1/approvals/{id}` |
| `DELETE /api/v1/approval-mgmt/{id}` | `DELETE /v1/approvals/{id}` |
| `POST /api/v1/approval-mgmt/{id}/submit` | `POST /v1/approvals/{id}/submit` |
| `POST /api/v1/approval-mgmt/{id}/approve` | `POST /v1/approvals/{id}/approve` |
| `POST /api/v1/approval-mgmt/{id}/reject` | `POST /v1/approvals/{id}/reject` |
| `POST /api/v1/approval-mgmt/{id}/cancel` | `POST /v1/approvals/{id}/cancel` |
| `POST /api/v1/approval-mgmt/{id}/hold` | `POST /v1/approvals/{id}/hold` |
| `POST /api/v1/approval-mgmt/{id}/release-hold` | `POST /v1/approvals/{id}/release-hold` |
| `POST /api/v1/approval-mgmt/{id}/pre-decide` | `POST /v1/approvals/{id}/pre-decide` |
| `POST /api/v1/approval-mgmt/{id}/copy` | `POST /v1/approvals/{id}/copy` |
| `GET /api/v1/approval-mgmt/forms` | `GET /v1/approval-forms/active` |
| `GET /api/v1/approval-mgmt/lines` | `GET /v1/approval-lines` |
| `POST /api/v1/approval-mgmt/upload-file` | (공통 File API 사용) |
| `GET /api/v1/approval-mgmt/badge-counts` | `GET /v1/approvals/badge-counts` |
### 7.3 서비스 클래스 비교
| 기능 | MNG `ApprovalService` | API `ApprovalService` |
|------|----------------------|----------------------|
| 기안함 | `getMyDrafts()` | `drafts()` |
| 결재함 | `getPendingForMe()` | `inbox()` |
| 완료함 | `getCompletedByMe()` | `completed()` |
| 참조함 | `getReferencesForMe()` | `reference()` |
| 현황 카드 | — | `draftsSummary()`, `inboxSummary()`, `completedSummary()` |
| 생성 | `createApproval()` | `store()` |
| 수정 | `updateApproval()` | `update()` |
| 삭제 | `deleteApproval()`, `forceDeleteApproval()` | `destroy()` |
| 상신 | `submitApproval()` | `submit()` |
| 승인 | `approveApprovalStep()` | `approve()` |
| 반려 | `rejectApprovalStep()` | `reject()` |
| 회수 | `cancelApproval()` | `cancel()` |
| 보류 | `holdApproval()` | `hold()` |
| 보류해제 | `releaseApprovalHold()` | `releaseHold()` |
| 전결 | `preDecide()` (ApprovalApiController 내) | `preDecide()` |
| 복사재기안 | `copyForRedraft()` | `copyForRedraft()` |
| 결재선 CRUD | `createLine()`, `updateLine()`, `deleteLine()` | `lineStore()`, `lineUpdate()`, `lineDestroy()` |
| 양식 CRUD | — | `formStore()`, `formUpdate()`, `formDestroy()` |
| 위임 CRUD | — | `delegationStore()`, `delegationUpdate()`, `delegationDestroy()` |
| 휴가 연동 | `handleApprovalCompleted/Rejected/Deleted/Cancelled()` | 내부 처리 |
| PDF 생성 | 컨트롤러에서 DomPDF 직접 호출 | ❌ 미구현 |
---
## 8. 모델 동기화 주의사항
### 8.1 동기화가 필요한 시점
| 이벤트 | 조치 |
|--------|------|
| API에서 마이그레이션 추가 | MNG 모델의 `$fillable`, `$casts` 업데이트 |
| API 모델에 새 관계 추가 | MNG 모델에도 동일 관계 추가 |
| API 모델에 새 상수 추가 | MNG 모델에도 동일 상수 추가 |
| MNG에서 새 헬퍼 메서드 추가 | API 모델에 반영 여부 판단 (UI 전용이면 불필요) |
### 8.2 현재 차이점
| 항목 | MNG 모델 | API 모델 |
|------|---------|---------|
| Trait | `BelongsToTenant`, `SoftDeletes` | `BelongsToTenant`, `SoftDeletes`, `Auditable`, `ModelTrait` |
| 네임스페이스 | `App\Models\Approvals` | `App\Models\Tenants` |
| 감사 로깅 | — | `Auditable` trait으로 자동 기록 |
---
## 9. React 구현 우선순위 제안
### Phase A: 기본 결재 (필수)
1. 기안함/결재함/완료함/참조함 목록 화면
2. 기안 작성 (양식 선택 → 결재선 지정 → 본문 작성 → 상신)
3. 결재 상세 조회 + 승인/반려/회수 액션
4. 결재선 에디터 (2패널 + 결재/참조 분리)
5. badge-counts (사이드바 뱃지)
### Phase B: 양식 확장
1. 지출결의서 전용 폼 (법인카드/송금/첨부파일)
2. 품의서 5종
3. 근태신청 (휴가 연동)
4. 결재서명란
### Phase C: 증명서/업무 양식
1. 재직/경력/위촉증명서 + PDF 다운로드
2. 사직서, 인감, 위임장, 의사록, 견적서, 공문서
3. 연차촉진통지서
### Phase D: 고급 기능
1. 위임 대결 (Phase 3)
2. 병렬 결재 (Phase 3)
3. 결재 통계/리포트 (Phase 4)
---
## 관련 문서
- [결재관리 개요](README.md) — 시스템 전체 개요
- [양식 기술 명세](form-types.md) — 양식별 필드, JSON 구조
- [워크플로우 상세](workflows.md) — 각 동작의 흐름
- [API 명세](api-reference.md) — 엔드포인트 목록
- [UI 화면 구성](ui-screens.md) — MNG 화면별 UI
- [DB 변경 및 모델 동기화](db-changes-and-model-sync.md) — 마이그레이션 이력
- [API 결재 연동 명세](../../frontend/api-specs/approval-api.md) — React용 API 명세
- [결재 통합 계획](../../dev/dev_plans/approval-system-unification-plan.md) — MNG→API 통합 계획
---
**최종 업데이트**: 2026-03-11