# 결재관리 API 명세 > **작성일**: 2026-03-11 > **상태**: 개발 완료 (API 배포됨) > **Base URL**: `api.codebridge-x.com` (운영) / `api.dev.codebridge-x.com` (개발) --- ## 1. 개요 결재관리 시스템의 전체 API 명세. 기안, 결재, 참조, 위임, 완료함 등 모든 결재 워크플로우를 지원한다. ### 1.1 인증 모든 요청에 다음 헤더가 필요하다: ``` X-API-KEY: {api_key} Authorization: Bearer {token} ``` ### 1.2 공통 응답 형식 ```json { "success": true, "message": "조회되었습니다.", "data": { ... } } ``` 에러 시: ```json { "success": false, "message": "에러 메시지" } ``` --- ## 2. 상태 흐름도 ``` ┌──────────┐ │ draft │ 임시저장 └────┬─────┘ │ submit (상신) ▼ ┌──────────┐ ┌────►│ pending │ 결재 진행중 │ └──┬─┬─┬──┘ │ │ │ │ release- │ hold │ │ │ approve (각 단계) hold │ ▼ │ │ │ │ ┌──────┐│ │ │ └─┤on_hold││ │ │ 보류 └──────┘│ │ │ │ │ │ ┌───────────────┘ │ └──────────────┐ │ cancel (회수) │ │ reject (반려) ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │cancelled │ │ approved │ │ rejected │ └──────────┘ └──────────┘ └──────────┘ │ │ submit (재상신) ▼ ┌──────────┐ │ pending │ └──────────┘ ``` ### 2.1 상태값 | 상태 | 값 | 설명 | UI 배지 색상 | |------|---|------|-------------| | 임시저장 | `draft` | 작성 중, 아직 미상신 | gray | | 진행중 | `pending` | 결재 진행 중 | blue | | 승인 | `approved` | 최종 승인 완료 | green | | 반려 | `rejected` | 결재자가 반려 | red | | 회수 | `cancelled` | 기안자가 회수 | yellow | | 보류 | `on_hold` | 결재자가 보류 | orange | ### 2.2 결재 단계 유형 | 유형 | 값 | 설명 | |------|---|------| | 결재 | `approval` | 승인/반려 권한 | | 합의 | `agreement` | 승인/반려 권한 (다른 부서) | | 참조 | `reference` | 열람만 가능 | ### 2.3 결재 단계 상태 | 상태 | 값 | 설명 | |------|---|------| | 대기 | `pending` | 아직 미처리 | | 승인 | `approved` | 승인함 | | 반려 | `rejected` | 반려함 | | 건너뜀 | `skipped` | 전결/회수로 건너뜀 | | 보류 | `on_hold` | 보류 중 | --- ## 3. 목록 API (탭별) ### 3.1 기안함 (내가 기안한 문서) ``` GET /api/v1/approvals/drafts ``` | 파라미터 | 타입 | 필수 | 설명 | |---------|------|:----:|------| | `status` | string | - | `draft`, `pending`, `approved`, `rejected`, `cancelled`, `on_hold` | | `search` | string | - | 제목/문서번호 검색 | | `sort_by` | string | - | `created_at`(기본), `drafted_at`, `completed_at`, `title`, `status` | | `sort_dir` | string | - | `asc`, `desc`(기본) | | `per_page` | int | - | 페이지당 건수 (기본 20) | | `page` | int | - | 페이지 번호 | **응답 데이터** (페이지네이션): ```json { "data": [ { "id": 1, "document_number": "APR-20260311-0001", "title": "출장 품의서", "status": "pending", "is_urgent": false, "drafted_at": "2026-03-11 10:00:00", "completed_at": null, "created_at": "2026-03-11", "form": { "id": 1, "name": "품의서", "code": "request", "category": "request" }, "drafter": { "id": 10, "name": "홍길동", "tenant_profile": { "department": { "id": 3, "name": "영업부" }, "position_key": "manager" } }, "steps": [ { "id": 1, "step_order": 1, "step_type": "approval", "status": "approved", "approver_name": "김팀장", "approver_department": "영업부", "approver_position": "팀장", "comment": null, "acted_at": "2026-03-11 11:00:00", "approver": { "id": 5, "name": "김팀장" } }, { "id": 2, "step_order": 2, "step_type": "approval", "status": "pending", "approver_name": "박부장", "approver_department": "영업부", "approver_position": "부장", "approver": { "id": 8, "name": "박부장" } } ] } ], "current_page": 1, "last_page": 3, "per_page": 20, "total": 52 } ``` --- ### 3.2 기안함 현황 카드 ``` GET /api/v1/approvals/drafts/summary ``` 파라미터 없음. ```json { "total": 52, "draft": 3, "pending": 12, "approved": 30, "rejected": 7 } ``` --- ### 3.3 결재함 (내가 결재할 문서) ``` GET /api/v1/approvals/inbox ``` | 파라미터 | 타입 | 필수 | 설명 | |---------|------|:----:|------| | `status` | string | - | `requested`(내 차례), `scheduled`(예정), `completed`(처리완료), `rejected`(내가 반려) | | `sort_by` | string | - | `created_at`(기본), `drafted_at`, `completed_at`, `title` | | `sort_dir` | string | - | `asc`, `desc`(기본) | | `start_date` | string | - | `YYYY-MM-DD` 시작일 | | `end_date` | string | - | `YYYY-MM-DD` 종료일 | | `per_page` | int | - | 페이지당 건수 | | `page` | int | - | 페이지 번호 | > **`requested`**: 현재 내가 처리해야 할 문서 (내 차례) > **`scheduled`**: 아직 내 차례가 아닌 문서 (앞 결재자가 미처리) --- ### 3.4 결재함 현황 카드 ``` GET /api/v1/approvals/inbox/summary ``` ```json { "requested": 5, "scheduled": 3, "completed": 20, "rejected": 2 } ``` --- ### 3.5 참조함 (내가 참조된 문서) ``` GET /api/v1/approvals/reference ``` | 파라미터 | 타입 | 필수 | 설명 | |---------|------|:----:|------| | `is_read` | boolean | - | `true`(읽음), `false`(안읽음) | | `sort_by` | string | - | `created_at`(기본), `drafted_at`, `completed_at`, `title` | | `sort_dir` | string | - | `asc`, `desc`(기본) | | `per_page` | int | - | 페이지당 건수 | | `page` | int | - | 페이지 번호 | --- ### 3.6 완료함 (내 기안 완료 + 내가 처리한 문서) ``` GET /api/v1/approvals/completed ``` IndexRequest와 동일한 파라미터 사용. --- ### 3.7 완료함 현황 카드 ``` GET /api/v1/approvals/completed/summary ``` ```json { "approved": 25, "rejected": 5, "cancelled": 2, "unread": 3 } ``` --- ### 3.8 뱃지 카운트 (사이드바/GNB용) ``` GET /api/v1/approvals/badge-counts ``` ```json { "pending": 5, "draft": 2, "reference_unread": 3, "completed_unread": 1 } ``` > **UI 활용**: 사이드바 메뉴 옆에 `pending` 뱃지, 참조 탭에 `reference_unread` 뱃지 등 --- ## 4. 문서 CRUD ### 4.1 문서 상세 ``` GET /api/v1/approvals/{id} ``` 상세 응답에는 `form.template` (양식 필드 정의), 전체 `steps` 목록, 연결된 `linkable` 문서 데이터가 포함된다. --- ### 4.2 문서 생성 (임시저장 또는 즉시 상신) ``` POST /api/v1/approvals ``` | 필드 | 타입 | 필수 | 설명 | |------|------|:----:|------| | `form_id` | int | O* | 결재 양식 ID (`form_code`와 택1) | | `form_code` | string | O* | 결재 양식 코드 (`form_id`와 택1) | | `title` | string | O | 제목 (최대 200자) | | `content` | object | O | 양식 데이터 (JSON) | | `body` | string | - | 본문 HTML | | `is_urgent` | boolean | - | 긴급 여부 | | `department_id` | int | - | 기안 부서 ID | | `line_id` | int | - | 결재선 템플릿 ID | | `attachments` | int[] | - | 첨부파일 ID 배열 | | `submit` | boolean | - | `true`면 즉시 상신 | | `steps` | array | 조건* | 결재선 (`submit=true`일 때 필수) | **steps 배열 항목**: | 필드 | 타입 | 설명 | |------|------|------| | `step_type` (또는 `type`) | string | `approval`, `agreement`, `reference` | | `approver_id` (또는 `user_id`) | int | 결재자 ID | | `step_order` | int | 순서 (생략 시 자동 부여) | ```json { "form_code": "request", "title": "출장 품의서", "content": { "destination": "부산", "purpose": "거래처 미팅", "amount": 500000 }, "submit": true, "steps": [ { "step_type": "approval", "user_id": 5 }, { "step_type": "approval", "user_id": 8 }, { "step_type": "reference", "user_id": 12 } ] } ``` > **참고**: `submit: false`이면 임시저장만 하고 `steps`는 선택 사항이다. --- ### 4.3 문서 수정 (임시저장 상태만) ``` PATCH /api/v1/approvals/{id} ``` 모든 필드 선택적. `steps`를 전달하면 기존 결재선을 교체한다. --- ### 4.4 문서 삭제 (임시저장/반려 상태만) ``` DELETE /api/v1/approvals/{id} ``` --- ## 5. 워크플로우 액션 ### 5.1 상신 (임시저장 → 진행중) ``` POST /api/v1/approvals/{id}/submit ``` | 필드 | 타입 | 필수 | 설명 | |------|------|:----:|------| | `steps` | array | - | 새 결재선 (생략 시 기존 결재선 사용) | > **재상신**: 반려 상태에서도 호출 가능. 반려 이력이 `rejection_history`에 자동 저장되고, `resubmit_count`가 1 증가한다. --- ### 5.2 승인 ``` POST /api/v1/approvals/{id}/approve ``` | 필드 | 타입 | 필수 | 설명 | |------|------|:----:|------| | `comment` | string | - | 승인 의견 (최대 1000자) | > 현재 내 차례인 결재 단계만 승인 가능. 마지막 결재자가 승인하면 문서 상태가 `approved`로 변경된다. --- ### 5.3 반려 ``` POST /api/v1/approvals/{id}/reject ``` | 필드 | 타입 | 필수 | 설명 | |------|------|:----:|------| | `comment` | string | **O** | 반려 사유 (필수, 최대 1000자) | --- ### 5.4 회수 (기안자만) ``` POST /api/v1/approvals/{id}/cancel ``` | 필드 | 타입 | 필수 | 설명 | |------|------|:----:|------| | `recall_reason` | string | - | 회수 사유 (최대 1000자) | > 첫 번째 결재자가 이미 처리한 경우 회수 불가 (에러 반환). --- ### 5.5 보류 (현재 결재자만) ``` POST /api/v1/approvals/{id}/hold ``` | 필드 | 타입 | 필수 | 설명 | |------|------|:----:|------| | `comment` | string | **O** | 보류 사유 (필수, 최대 1000자) | --- ### 5.6 보류 해제 (보류한 결재자만) ``` POST /api/v1/approvals/{id}/release-hold ``` 파라미터 없음. 보류 상태를 다시 진행중으로 되돌린다. --- ### 5.7 전결 (현재 결재자가 최종 승인) ``` POST /api/v1/approvals/{id}/pre-decide ``` | 필드 | 타입 | 필수 | 설명 | |------|------|:----:|------| | `comment` | string | - | 전결 의견 (최대 1000자) | > 현재 결재자 이후의 모든 단계를 `skipped`로 변경하고 문서를 `approved`로 확정한다. --- ### 5.8 복사 재기안 ``` POST /api/v1/approvals/{id}/copy ``` 파라미터 없음. 완료/반려/회수된 문서를 복사하여 새 임시저장 문서를 생성한다. 결재선(스냅샷 포함)도 함께 복사된다. **응답**: 새로 생성된 Approval 객체 --- ## 6. 참조 열람 관리 ### 6.1 참조 열람 처리 ``` POST /api/v1/approvals/{id}/read ``` ### 6.2 참조 미열람 처리 ``` POST /api/v1/approvals/{id}/unread ``` ### 6.3 완료함 일괄 읽음 처리 ``` POST /api/v1/approvals/completed/mark-read ``` > 기안자의 미읽음 완료 문서를 일괄로 읽음 처리한다. --- ## 7. 위임 관리 부재 시 다른 사용자에게 결재 권한을 위임한다. ### 7.1 위임 목록 ``` GET /api/v1/approvals/delegations ``` --- ### 7.2 위임 생성 ``` POST /api/v1/approvals/delegations ``` | 필드 | 타입 | 필수 | 설명 | |------|------|:----:|------| | `delegate_id` | int | **O** | 대리자 ID | | `start_date` | string | **O** | 시작일 (`YYYY-MM-DD`, 오늘 이후) | | `end_date` | string | **O** | 종료일 (`YYYY-MM-DD`, 시작일 이후) | | `form_ids` | int[] | - | 특정 양식만 위임 (생략 시 전체) | | `notify_delegator` | boolean | - | 위임자에게 알림 여부 | | `reason` | string | - | 위임 사유 (최대 500자) | --- ### 7.3 위임 수정 ``` PATCH /api/v1/approvals/delegations/{id} ``` 모든 필드 선택적. `is_active: false`로 비활성화 가능. --- ### 7.4 위임 삭제 ``` DELETE /api/v1/approvals/delegations/{id} ``` --- ## 8. 결재 양식 API ### 8.1 양식 목록 ``` GET /api/v1/approval-forms ``` ### 8.2 활성 양식 목록 (기안 시 드롭다운용) ``` GET /api/v1/approval-forms/active ``` ### 8.3 양식 상세 ``` GET /api/v1/approval-forms/{id} ``` ### 8.4 양식 생성 ``` POST /api/v1/approval-forms ``` ### 8.5 양식 수정 ``` PATCH /api/v1/approval-forms/{id} ``` ### 8.6 양식 삭제 ``` DELETE /api/v1/approval-forms/{id} ``` --- ## 9. 결재선 템플릿 API ### 9.1 결재선 목록 ``` GET /api/v1/approval-lines ``` ### 9.2 결재선 상세 ``` GET /api/v1/approval-lines/{id} ``` ### 9.3 결재선 생성 ``` POST /api/v1/approval-lines ``` ### 9.4 결재선 수정 ``` PATCH /api/v1/approval-lines/{id} ``` ### 9.5 결재선 삭제 ``` DELETE /api/v1/approval-lines/{id} ``` --- ## 10. 화면 구성 가이드 ### 10.1 메인 탭 구조 ``` ┌─────────┬─────────┬─────────┬─────────┐ │ 기안함 │ 결재함 │ 참조함 │ 완료함 │ │ (drafts)│ (inbox) │(reference│(completed│ │ │ [5] │) [3] │) [1] │ └─────────┴─────────┴─────────┴─────────┘ ``` - 각 탭의 뱃지 숫자는 `GET /badge-counts`로 가져온다 - `pending` → 결재함 뱃지 - `reference_unread` → 참조함 뱃지 - `completed_unread` → 완료함 뱃지 ### 10.2 결재함 서브 필터 | 필터 | status 값 | 설명 | |------|----------|------| | 결재 요청 | `requested` | 현재 내 차례 (액션 버튼 표시) | | 예정 | `scheduled` | 내 차례 대기 | | 처리 완료 | `completed` | 내가 처리한 문서 | | 반려 | `rejected` | 내가 반려한 문서 | ### 10.3 문서 상세 페이지 액션 버튼 | 조건 | 표시할 버튼 | |------|-----------| | 내가 기안자 + `draft`/`rejected` | 수정, 삭제, 상신 | | 내가 기안자 + `pending`/`on_hold` | 회수 | | 내가 현재 결재자 + `pending` | 승인, 반려, 보류, 전결 | | 내가 보류한 결재자 + `on_hold` | 보류해제 | | `approved`/`rejected`/`cancelled` | 복사 재기안 | | 내가 참조자 | 열람/미열람 토글 | ### 10.4 결재선 표시 결재 단계를 순서대로 표시한다. 각 단계에 스냅샷 정보를 사용한다: ``` [1] 결재 | 김팀장 (영업부/팀장) → 승인 ✓ (2026-03-11 11:00) [2] 결재 | 박부장 (영업부/부장) → 대기 중 ◯ [3] 합의 | 이과장 (재무부/과장) → 대기 중 ◯ [4] 참조 | 정대리 (인사부/대리) → 미열람 ``` > **스냅샷 필드**: `approver_name`, `approver_department`, `approver_position`은 결재선 생성 시점의 정보가 저장된다. 결재자가 부서 이동해도 결재 당시 정보가 유지된다. --- ## 관련 문서 - `dev/dev_plans/approval-system-unification-plan.md` - 결재 시스템 통합 계획서 - `frontend/api-specs/document-api-integration.md` - 문서 API 연동 명세 --- **최종 업데이트**: 2026-03-11