From 013a7a38ebd1fe4ee54558c2a533d8d55862e562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Thu, 19 Mar 2026 09:03:19 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20[material]=20=EB=B6=80=EC=A0=81?= =?UTF-8?q?=ED=95=A9=EA=B4=80=EB=A6=AC=20FE=20=EB=AA=85=EC=84=B8=20?= =?UTF-8?q?=EA=B2=B0=EC=9E=AC=20=EC=97=B0=EB=8F=99=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 3.8 결재상신 API 섹션 추가 (요청/응답 예시) - 단건 조회 응답에 approval 필드 추가 - 상태별 UI 제어 테이블 업데이트 - Server Actions에 submitNonconformingApproval 추가 --- frontend/api-specs/nonconforming-api.md | 84 +++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 4 deletions(-) diff --git a/frontend/api-specs/nonconforming-api.md b/frontend/api-specs/nonconforming-api.md index 1dae404..9f54097 100644 --- a/frontend/api-specs/nonconforming-api.md +++ b/frontend/api-specs/nonconforming-api.md @@ -1,7 +1,7 @@ # 부적합관리 API 명세 > **작성일**: 2026-03-19 -> **상태**: Phase 1 API 완료 +> **상태**: Phase 1+2 API 완료 (결재 연동 포함) > **대상**: React 프론트엔드 개발자 > **라우트**: `/material/nonconforming-management` @@ -55,7 +55,8 @@ ``` RECEIVED → ANALYZING (조건 없음) ANALYZING → RESOLVED (cause_analysis + corrective_action 필수) -RESOLVED → CLOSED (결재 승인 시 — Phase 2) +RESOLVED → (결재상신) → 결재 승인 시 자동 CLOSED + 결재 반려/회수 시 → RESOLVED 유지 (재상신 가능) ``` > `CLOSED` 상태에서는 수정/삭제 불가 (API가 403 반환) @@ -194,6 +195,24 @@ GET /api/v1/material/nonconforming-reports/{id} } ], "files": [], + "approval": { + "id": 10, + "document_number": "AP-20260319-0001", + "status": "pending", + "completed_at": null, + "steps": [ + { + "id": 1, + "step_order": 1, + "step_type": "approval", + "approver_id": 3, + "status": "pending", + "comment": null, + "acted_at": null, + "approver": { "id": 3, "name": "홍길동" } + } + ] + }, "creator": { "id": 5, "name": "김보곤" }, "created_at": "2026-03-19", "updated_at": "2026-03-19" @@ -201,6 +220,9 @@ GET /api/v1/material/nonconforming-reports/{id} } ``` +> `approval`은 결재상신 전에는 `null`. 결재 진행 중이면 `status: "pending"`, 승인 완료 시 `"approved"`. +``` + --- ### 3.4 등록 @@ -327,6 +349,47 @@ PATCH /api/v1/material/nonconforming-reports/{id}/status --- +### 3.8 결재상신 + +``` +POST /api/v1/material/nonconforming-reports/{id}/submit-approval +``` + +> `RESOLVED` 상태에서만 가능. 이미 결재가 연결된 경우 422 에러. + +**요청 Body**: + +```json +{ + "title": "부적합 처리 결재 - NC-20260319-001", + "form_id": 5, + "steps": [ + { "approver_id": 3, "step_type": "approval" }, + { "approver_id": 7, "step_type": "approval" } + ] +} +``` + +| 필드 | 타입 | 필수 | 설명 | +|------|------|:----:|------| +| `title` | string | - | 결재 제목 (미입력 시 자동 생성) | +| `form_id` | int | - | 결재 양식 ID | +| `steps` | array | ✅ | 결재선 (최소 1명) | +| `steps[].approver_id` | int | ✅ | 결재자 사용자 ID | +| `steps[].step_type` | string | - | `approval`(결재), `agreement`(합의), `reference`(참조) — 기본: `approval` | + +**결재 결과에 따른 부적합 상태 변화**: + +| 결재 결과 | 부적합 상태 | 설명 | +|----------|-----------|------| +| 승인 (`approved`) | → `CLOSED` | 종결 (수정 불가) | +| 반려 (`rejected`) | `RESOLVED` 유지 | `approval_id` 해제, 재상신 가능 | +| 회수 (`cancelled`) | `RESOLVED` 유지 | `approval_id` 해제, 재상신 가능 | + +**응답**: 단건 조회와 동일 (approval 정보 포함) + +--- + ## 4. 화면별 구현 가이드 ### 4.1 목록 페이지 @@ -395,8 +458,9 @@ PATCH /api/v1/material/nonconforming-reports/{id}/status |------|:---------:|----------| | `RECEIVED` | ✅ | "분석 시작" → `ANALYZING` | | `ANALYZING` | ✅ | "조치 완료" → `RESOLVED` (원인분석+처리방안 필수) | -| `RESOLVED` | ✅ | "결재상신" (Phase 2) | -| `CLOSED` | ❌ 읽기전용 | 없음 | +| `RESOLVED` | ✅ | "결재상신" → submit-approval API 호출 | +| `RESOLVED` + 결재중 | ❌ | 결재 진행 상태 표시 (기존 결재 시스템 UI) | +| `CLOSED` | ❌ 읽기전용 | 없음 (결재 승인으로 자동 전환됨) | --- @@ -486,6 +550,18 @@ export async function changeNonconformingStatus(id: number, status: string) { body: { status }, }); } + +// 결재상신 +export async function submitNonconformingApproval( + id: number, + data: { title?: string; form_id?: number; steps: Array<{ approver_id: number; step_type?: string }> } +) { + return executeServerAction({ + url: buildApiUrl(`/api/v1/material/nonconforming-reports/${id}/submit-approval`), + method: 'POST', + body: data, + }); +} ``` ---