# 결재관리 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
