docs: [material] 부적합관리 FE 명세 결재 연동 추가

- 3.8 결재상신 API 섹션 추가 (요청/응답 예시)
- 단건 조회 응답에 approval 필드 추가
- 상태별 UI 제어 테이블 업데이트
- Server Actions에 submitNonconformingApproval 추가
This commit is contained in:
김보곤
2026-03-19 09:03:19 +09:00
parent 0b17df6a45
commit 013a7a38eb

View File

@@ -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,
});
}
```
---