Files
sam-docs/sam/docs/features/approvals/api-reference.md
김보곤 490477421d docs: [approvals] 결재관리 시스템 문서 4종 작성
- README.md: 시스템 개요, 아키텍처, DB 스키마, 상태 관리, 권한 매트릭스
- workflows.md: 워크플로우 상세 (승인/반려/회수/보류/전결/복사재기안)
- api-reference.md: API 엔드포인트 20개 명세
- ui-screens.md: UI 화면 구성 및 인터랙션
- INDEX.md에 결재관리 문서 등록
2026-02-28 00:09:08 +09:00

11 KiB

결재관리 API 명세

작성일: 2026-02-28 상태: Phase 2 구현 완료 Base URL: /api/admin/approvals 미들웨어: web, auth, hq.member 관련: README.md | 워크플로우 | UI 화면


1. 개요

모든 API는 JSON 응답을 반환한다. 인증은 세션 기반이며, CSRF 토큰이 필요하다.

1.1 공통 응답 형식

성공:

{
  "success": true,
  "message": "처리 메시지",
  "data": { ... }
}

실패 (400):

{
  "success": false,
  "message": "에러 메시지"
}

1.2 공통 헤더

Content-Type: application/json
Accept: application/json
X-CSRF-TOKEN: {csrf_token}

2. 목록 조회 API

2.1 기안함

내가 기안한 문서 목록을 조회한다.

GET /api/admin/approvals/drafts

Query Parameters:

파라미터 타입 설명
search string 제목/문서번호 검색
status string 상태 필터 (draft, pending, approved, rejected, cancelled, on_hold)
is_urgent boolean 긴급 문서만
date_from date 시작일 (YYYY-MM-DD)
date_to date 종료일 (YYYY-MM-DD)
per_page int 페이지당 건수 (기본 15)
page int 페이지 번호

응답: Laravel 페이지네이션 형식

{
  "data": [
    {
      "id": 1,
      "document_number": "APR-260228-001",
      "title": "휴가 신청",
      "status": "pending",
      "is_urgent": false,
      "form": { "id": 1, "name": "휴가신청서" },
      "steps": [...],
      "created_at": "2026-02-28T10:00:00",
      "drafted_at": "2026-02-28T10:05:00"
    }
  ],
  "current_page": 1,
  "last_page": 3,
  "per_page": 15,
  "total": 42
}

2.2 결재 대기함

내가 현재 결재해야 할 문서 목록을 조회한다.

GET /api/admin/approvals/pending

Query Parameters:

파라미터 타입 설명
search string 제목/문서번호 검색
is_urgent boolean 긴급 문서만
date_from date 시작일
date_to date 종료일
per_page int 페이지당 건수

현재 사용자가 결재 차례인 문서만 표시된다. 이미 승인/반려한 문서는 표시되지 않는다.


2.3 처리 완료함

내가 승인 또는 반려한 문서 목록을 조회한다.

GET /api/admin/approvals/completed

Query Parameters:

파라미터 타입 설명
search string 제목/문서번호 검색
status string 상태 필터
date_from date 시작일
date_to date 종료일
per_page int 페이지당 건수

2.4 참조함

내가 참조자로 지정된 문서 목록을 조회한다.

GET /api/admin/approvals/references

Query Parameters:

파라미터 타입 설명
search string 제목/문서번호 검색
is_read string 열람 상태 필터 (true=열람완료, false=미열람)
date_from date 시작일
date_to date 종료일
per_page int 페이지당 건수

3. CRUD API

3.1 상세 조회

GET /api/admin/approvals/{id}

응답:

{
  "success": true,
  "data": {
    "id": 1,
    "tenant_id": 1,
    "document_number": "APR-260228-001",
    "form_id": 1,
    "line_id": null,
    "title": "휴가 신청",
    "content": {},
    "body": "2월 27일~28일 연차 사용 신청합니다.",
    "status": "pending",
    "is_urgent": false,
    "drafter_id": 10,
    "department_id": 3,
    "current_step": 2,
    "drafted_at": "2026-02-28T10:05:00",
    "completed_at": null,
    "recall_reason": null,
    "parent_doc_id": null,
    "form": { "id": 1, "name": "휴가신청서" },
    "drafter": { "id": 10, "name": "홍길동" },
    "line": null,
    "steps": [
      {
        "id": 1,
        "step_order": 1,
        "step_type": "approval",
        "approver_id": 20,
        "approver_name": "김과장",
        "approver_department": "경영지원팀",
        "approver_position": "과장",
        "status": "approved",
        "approval_type": "normal",
        "comment": "승인합니다.",
        "acted_at": "2026-02-28T11:00:00",
        "is_read": false,
        "read_at": null
      },
      {
        "id": 2,
        "step_order": 2,
        "step_type": "approval",
        "approver_id": 30,
        "approver_name": "박부장",
        "approver_department": "경영지원팀",
        "approver_position": "부장",
        "status": "pending",
        "approval_type": "normal",
        "comment": null,
        "acted_at": null,
        "is_read": false,
        "read_at": null
      }
    ]
  }
}

3.2 생성 (임시저장)

POST /api/admin/approvals

Request Body:

{
  "form_id": 1,
  "title": "휴가 신청",
  "body": "2월 27일~28일 연차 사용",
  "is_urgent": false,
  "steps": [
    { "user_id": 20, "step_type": "approval" },
    { "user_id": 30, "step_type": "approval" },
    { "user_id": 40, "step_type": "reference" }
  ]
}

Validation:

필드 규칙
form_id required, exists:approval_forms,id
title required, string, max:200
body nullable, string
is_urgent boolean
steps nullable, array
steps.*.user_id required_with:steps, exists:users,id
steps.*.step_type required_with:steps, in:approval,agreement,reference

응답 (201):

{
  "success": true,
  "message": "결재 문서가 저장되었습니다.",
  "data": { ... }
}

3.3 수정

PUT /api/admin/approvals/{id}

draft 또는 rejected 상태에서만 수정 가능

Request Body: (생성과 동일, 모든 필드 선택)

Validation:

필드 규칙
title sometimes, string, max:200
body nullable, string
is_urgent boolean
steps nullable, array

3.4 삭제

DELETE /api/admin/approvals/{id}

draft 상태에서만 삭제 가능

응답:

{
  "success": true,
  "message": "결재 문서가 삭제되었습니다."
}

4. 워크플로우 API

4.1 상신

POST /api/admin/approvals/{id}/submit

기안자가 draft/rejected 문서를 결재 요청한다.

Request Body: 없음

응답: { "success": true, "message": "결재가 상신되었습니다.", "data": {...} }


4.2 승인

POST /api/admin/approvals/{id}/approve

현재 결재자가 승인한다.

Request Body:

{
  "comment": "승인합니다."  // 선택
}

응답: { "success": true, "message": "승인되었습니다.", "data": {...} }


4.3 반려

POST /api/admin/approvals/{id}/reject

현재 결재자가 반려한다. 사유 필수.

Request Body:

{
  "comment": "예산 초과로 반려합니다."  // 필수
}

Validation: comment — required, string, max:1000

응답: { "success": true, "message": "반려되었습니다.", "data": {...} }


4.4 회수

POST /api/admin/approvals/{id}/cancel

기안자가 pending/on_hold 문서를 회수한다. 첫 결재자 미처리 시에만 가능.

Request Body:

{
  "recall_reason": "내용 수정 필요"  // 선택
}

응답: { "success": true, "message": "결재가 회수되었습니다.", "data": {...} }


4.5 보류

POST /api/admin/approvals/{id}/hold

현재 결재자가 결재를 보류한다. 사유 필수.

Request Body:

{
  "comment": "추가 자료 검토 필요"  // 필수
}

Validation: comment — required, string, max:1000

응답: { "success": true, "message": "보류되었습니다.", "data": {...} }


4.6 보류 해제

POST /api/admin/approvals/{id}/release-hold

보류한 결재자가 보류를 해제한다.

Request Body: 없음

응답: { "success": true, "message": "보류가 해제되었습니다.", "data": {...} }


4.7 전결

POST /api/admin/approvals/{id}/pre-decide

현재 결재자가 이후 모든 결재를 건너뛰고 최종 승인한다.

Request Body:

{
  "comment": "전결 처리합니다."  // 선택
}

응답: { "success": true, "message": "전결 처리되었습니다.", "data": {...} }


4.8 복사 재기안

POST /api/admin/approvals/{id}/copy

기안자가 approved/rejected/cancelled 문서를 복사하여 새 draft를 생성한다.

Request Body: 없음

응답:

{
  "success": true,
  "message": "문서가 복사되었습니다.",
  "data": {
    "id": 15,
    "document_number": "APR-260228-003",
    "parent_doc_id": 1,
    "status": "draft",
    ...
  }
}

응답의 data.id를 사용하여 /approval-mgmt/{id}/edit로 이동한다.


4.9 참조 열람 추적

POST /api/admin/approvals/{id}/mark-read

참조자가 문서를 열람했음을 기록한다.

Request Body: 없음

응답: { "success": true, "message": "열람 처리되었습니다." }


5. 유틸리티 API

5.1 결재선 템플릿 목록

GET /api/admin/approvals/lines

응답:

{
  "success": true,
  "data": [
    { "id": 1, "name": "일반 결재선", "steps": [...] }
  ]
}

5.2 양식 목록

GET /api/admin/approvals/forms

응답:

{
  "success": true,
  "data": [
    { "id": 1, "name": "휴가신청서", "is_active": true }
  ]
}

5.3 미처리 건수 (뱃지)

GET /api/admin/approvals/badge-counts

응답:

{
  "success": true,
  "data": {
    "pending": 3,
    "draft": 1,
    "reference_unread": 5
  }
}
필드 설명
pending 내가 결재해야 할 문서 수
draft 내 임시저장 문서 수
reference_unread 미열람 참조 문서 수

6. 라우트 전체 목록

Method Path 컨트롤러 메서드 이름 설명
GET /drafts drafts drafts 기안함
GET /pending pending pending 결재 대기함
GET /completed completed completed 처리 완료함
GET /references references references 참조함
GET /lines lines lines 결재선 템플릿
GET /forms forms forms 양식 목록
GET /badge-counts badgeCounts badge-counts 뱃지 건수
POST / store store 생성
GET /{id} show show 상세
PUT /{id} update update 수정
DELETE /{id} destroy destroy 삭제
POST /{id}/submit submit submit 상신
POST /{id}/approve approve approve 승인
POST /{id}/reject reject reject 반려
POST /{id}/cancel cancel cancel 회수
POST /{id}/hold hold hold 보류
POST /{id}/release-hold releaseHold release-hold 보류 해제
POST /{id}/pre-decide preDecide pre-decide 전결
POST /{id}/copy copyForRedraft copy 복사 재기안
POST /{id}/mark-read markAsRead mark-read 열람 추적

관련 문서


최종 업데이트: 2026-02-28