# Phase 5.1: 중간검사(PQC) 폼 구현 계획

> **작성일**: 2026-02-10
> **마스터 문서**: [`document-system-master.md`](./document-system-master.md)
> **기존 설계**: [`document-management-system-plan.md`](./document-management-system-plan.md) 섹션 5.2~5.3
> **상태**: 🔄 진행 중 (5/6)
> **선행 조건**: Phase 5.0 ✅ 완료됨

---

## 1. 개요

### 1.1 목적
mng에서 중간검사 양식 템플릿을 완성하고, React 작업자 화면(`/production/worker-screen`)의 중간검사 모달에서 해당 양식 기반으로 검사 데이터를 입력/저장/조회할 수 있도록 한다.

### 1.2 현재 상태

| 항목 | 상태 | 비고 |
|------|:----:|------|
| mng 시더 (4종) | ✅ | MidInspectionTemplateSeeder: 조인트바(10), 슬랫(11), 스크린(12), 절곡품(13) |
| mng edit.blade.php 탭 | ✅ | 4개 탭 (기본정보/기본필드/검사기준서/컬럼) |
| 검사 기준 이미지 | ✅ | 27개 파일 → `mng/public/img/inspection/` |
| 스키마 정합성 | ✅ | 컬럼 모두 존재 확인 (2026-02-10 분석) |
| section_fields | ✅ | Phase 5.0.2에서 해결: MidInspection 7필드, IncomingInspection 6필드 |
| ProcessStep.document_template_id | ✅ | 2026-02-10 마이그레이션 추가됨 |
| React 중간검사 모달 | ✅ | InspectionReportModal + TemplateInspectionContent (양식 기반 동적 렌더링) |
| React 검사 입력 모달 | ✅ | InspectionInputModal + DynamicInspectionForm (양식 기반) |
| API 검사 문서 생성 | ✅ | createInspectionDocument() 완전 구현. 정규화+레거시 자동 변환 |
| API 검사 데이터 조회 | ✅ | getInspectionTemplate(), resolveInspectionDocument(), getInspectionData() |
| 결재 워크플로우 | ⏳ | API 결재 엔드포인트 준비됨, 프론트 연동 필요 |

### 1.3 성공 기준
1. mng에서 4종 중간검사 양식 편집/미리보기 정상 동작
2. React 작업자 화면에서 양식 기반 중간검사 입력 가능
3. 개소별(WorkOrderItem별) 검사 데이터 EAV 저장/조회 가능
4. 결재 워크플로우(작성→검토→승인) 정상 동작

---

## 2. 데이터 흐름

```
WorkOrder (작업지시)
├─ process_id → Process (공정: 스크린/슬랫/절곡)
├─ sales_order_id → Order (수주)
└─ items: WorkOrderItem[]
   ├─ [0] itemName="와이어 스크린", source_order_item_id → OrderItem
   ├─ [1] itemName="메쉬 스크린"
   └─ [N] ...
       ↓
ProcessStep (공정단계)
├─ needs_inspection = true
├─ document_template_id → DocumentTemplate (중간검사 양식)
└─ step_name = "중간검사"
       ↓
Document (중간검사 문서)
├─ template_id → DocumentTemplate
├─ linkable_type = 'WorkOrder'
├─ linkable_id = work_order.id
├─ status: DRAFT → PENDING → APPROVED
└─ document_data (EAV)
   ├─ 기본필드: 품명, 규격, LOT NO, 발주처, 현장명, 검사일자, 검사자
   ├─ 검사데이터: 행(row) = 개소별, 열(column) = 검사항목
   │   ├─ s{섹션}_r{행}_c{컬럼}_sub{인덱스}
   │   └─ 예: s1_r0_c4_sub0 = "7400" (1번 개소의 길이 도면치수)
   └─ Footer: 부적합내용, 종합판정
```

### 2.1 조인트바 처리 (슬랫 하위)

```
Process: 슬랫
└─ ProcessStep: "중간검사"
   └─ document_template_id: 슬랫 양식(11) 또는 조인트바 양식(10)

React 판별 로직:
if (isJointBar || items?.some(i => i.productName?.includes('조인트바')))
  → SlatJointBarInspectionContent (조인트바 양식)
else
  → SlatInspectionContent (슬랫 양식)
```

**조인트바 양식 선택 방법** (2가지 옵션):
- **Option A**: WorkOrderItem의 productName으로 프론트에서 분기 (현재 방식)
- **Option B**: ProcessStep에 별도 document_template_id 매핑 (권장)

---

## 3. 작업 항목

| # | 작업 | 상태 | 완료 기준 | 비고 |
|---|------|:----:|----------|------|
| 5.1.1 | ~~mng 스키마 정합성 수정~~ → section_fields 생성 | ✅ | Phase 5.0.2에서 해결. MidInspection 7필드, IncomingInspection 6필드 | createSectionFields() 구현 |
| 5.1.2 | mng 중간검사 양식 편집/미리보기 검증 | ✅ | 4종 양식 모두 edit → 미리보기 → 저장 정상 동작 | edit.blade.php 4탭 CRUD |
| 5.1.3 | API 중간검사 문서 생성 연동 | ✅ | createInspectionDocument() 완전 구현. 기존 DRAFT/REJECTED 문서 update, 없으면 create | WorkOrderService line 1810+ |
| 5.1.4 | React 중간검사 모달 → 양식 기반 전환 | ✅ | TemplateInspectionContent 구현. 템플릿/레거시 모드 병행 | InspectionReportModal 두 가지 모드 |
| 5.1.5 | 개소별 검사 데이터 저장/조회 | ✅ | getInspectionData, saveInspectionDocument 구현. 정규화 레코드 형식 | section_id/column_id/row_index/field_key |
| 5.1.6 | 결재 워크플로우 연동 | ⏳ | 작성→검토→승인 3단계 결재. API 엔드포인트 준비됨 | 프론트 결재 UI 연동 필요 |

---

## 4. 공정별 검사 구조 (React 현재)

### 4.1 스크린 (ScreenInspectionContent)

| # | 검사항목 | 타입 | 기준 |
|---|---------|------|------|
| 1 | 가공상태 | check | 양호/불량 |
| 2 | 재봉상태 | check | 양호/불량 |
| 3 | 조립상태 | check | 양호/불량 |
| 4 | 길이 | complex | 도면치수 ±4mm |
| 5 | 나비(높이) | complex | 도면치수 ±40mm |
| 6 | 간격 | complex | 400 이하 → OK/NG |

- **행 수**: WorkOrderItem 수 (개소별 1행)
- **mng 양식 ID**: 12

### 4.2 슬랫 (SlatInspectionContent)

| # | 검사항목 | 타입 | 기준 |
|---|---------|------|------|
| 1 | 가공상태 | check | 양호/불량 |
| 2 | 조립상태 | check | 양호/불량 |
| 3 | 높이(1) | complex | 16.5 ± 1mm |
| 4 | 높이(2) | complex | 14.5 ± 1mm |
| 5 | 길이(엔드락제외) | complex | 도면치수 ±4mm |

- **행 수**: WorkOrderItem 수 (개소별 1행)
- **mng 양식 ID**: 11

### 4.3 조인트바 (SlatJointBarInspectionContent) - 슬랫 하위

| # | 검사항목 | 타입 | 기준 |
|---|---------|------|------|
| 1 | 가공상태 | check | 양호/불량 |
| 2 | 조립상태 | check | 양호/불량 |
| 3 | 높이(1) | complex | 16.5 ± 1mm |
| 4 | 높이(2) | complex | 14.5 ± 1mm |
| 5 | 길이 | complex | 300 ± 4mm |
| 6 | 간격 | complex | 150 ± 4mm |

- **행 수**: 단일 행 (제품 1건 단위)
- **mng 양식 ID**: 10

### 4.4 절곡 (BendingInspectionContent)

| # | 검사항목 | 타입 | 기준 |
|---|---------|------|------|
| 1 | 절곡상태 | check | 양호/불량 |
| 2 | 길이 | complex | 도면치수 ±4mm |
| 3 | 너비 | complex | 도면치수 |
| 4 | 간격 | complex | 5개 포인트 (좌우 각) ±2mm |

- **행 수**: 구성품별 동적 (제품 코드에 따라 다름)
- **mng 양식 ID**: 13
- **특이사항**: 제품코드(KSS01/KSS02/KWE01)와 마감유형(S1/S2/S3)에 따라 검사항목 동적 변경

### 4.5 절곡 재공품 (BendingWipInspectionContent)

| # | 검사항목 | 타입 | 기준 |
|---|---------|------|------|
| 1 | 절곡상태 | check | 양호/불량 |
| 2 | 길이 | complex | 고정값 |
| 3 | 너비 | complex | 고정값 |
| 4 | 간격 | complex | 고정값 |

- **mng 양식**: 신규 생성 필요 (또는 절곡 양식에 통합)

---

## 5. 핵심 파일 경로

### mng
| 파일 | 용도 |
|------|------|
| `mng/resources/views/document-templates/edit.blade.php` | 양식 편집 UI |
| `mng/app/Http/Controllers/DocumentTemplateController.php` | 양식 CRUD |
| `mng/database/seeders/MidInspectionTemplateSeeder.php` | 중간검사 시더 |
| `mng/app/Models/DocumentTemplate*.php` | 양식 모델 |

### api
| 파일 | 용도 |
|------|------|
| `api/app/Http/Controllers/V1/DocumentTemplateController.php` | 양식 조회 API |
| `api/app/Http/Controllers/V1/DocumentController.php` | 문서 CRUD API |
| `api/app/Models/Documents/Document.php` | 문서 모델 |
| `api/database/migrations/2026_02_10_*` | ProcessStep.document_template_id |

### react
| 파일 | 용도 |
|------|------|
| `react/src/components/production/WorkOrders/documents/InspectionReportModal.tsx` | 중간검사 성적서 모달 (템플릿/레거시 모드 병행) |
| `react/src/components/production/WorkOrders/documents/TemplateInspectionContent.tsx` | ✅ 양식 기반 동적 검사 렌더링 (NEW) |
| `react/src/components/production/WorkOrders/documents/inspection-shared.tsx` | 공유 컴포넌트/유틸 |
| `react/src/components/production/WorkOrders/documents/Screen|Slat|Bending*.tsx` | 공정별 레거시 검사 Content |
| `react/src/components/production/WorkerScreen/InspectionInputModal.tsx` | 검사 입력 모달 (DynamicInspectionForm 포함) |
| `react/src/components/production/WorkerScreen/actions.ts` | 작업자 화면 API 호출 |

---

## 6. 알려진 이슈

### 6.1 ~~스키마 불일치~~ → ✅ section_fields 해결됨 (Phase 5.0.2)
- **기존 오해**: Controller가 DB에 없는 컬럼에 접근한다고 판단
- **실제 상황**: `tolerance`, `standard_criteria`, `measurement_type`, `frequency_n`, `frequency_c`, `field_values` 컬럼 **모두 존재** (마이그레이션 순차 추가됨)
- **실제 문제**: 중간검사 템플릿에 `document_template_section_fields` 레코드가 없었음
- **해결 완료**: Phase 5.0.2에서 MidInspectionTemplateSeeder에 section_fields 7필드 생성 (category, item, standard, tolerance, method, measurement_type, frequency)

### 6.1.1 columns 자동 파생 (방안1)
- **결정**: items.measurement_type → columns 자동 파생 (마스터 문서 결정사항 #9)
- columns 정의는 시더에서 생략 가능 → 저장 시 자동 생성
- 상세: [마스터 문서 섹션 7.5](./document-system-master.md#75-방안1-columns-자동-파생-설계)

### 6.2 절곡품 동적 구성
- 제품 코드별로 검사항목이 완전히 달라짐 (구성품 수, 포인트 수 등)
- 기존 계획의 Option C 권장: 기본 양식에 구성품 목록만 정의, 문서 생성 시 제품 코드에 따라 동적 행 구성

### 6.3 절곡 재공품 양식 미존재
- BendingWipInspectionContent에 대응하는 mng 양식 없음
- 신규 시더 추가 또는 절곡 양식에 통합 필요

---

## 7. 변경 이력

| 날짜 | 내용 |
|------|------|
| 2026-02-10 | Phase 5.1 계획 문서 신규 생성 |
| 2026-02-10 | 이슈 6.1 수정: 스키마 불일치→section_fields 누락. 방안1 채택(columns 자동 파생). 선행조건 Phase 5.0 추가 |
| 2026-02-11 | 5.1.1 완료: Phase 5.0.2에서 section_fields 해결 (MidInspection 7필드) |
| 2026-02-11 | 5.1.2 완료: mng 양식 편집/미리보기 정상 동작 확인 |
| 2026-02-11 | 5.1.3 완료: createInspectionDocument() 완전 구현. 정규화+레거시 형식 지원 |
| 2026-02-11 | 5.1.4 완료: TemplateInspectionContent 양식 기반 동적 렌더링. 템플릿/레거시 모드 병행 |
| 2026-02-11 | 5.1.5 완료: getInspectionData, saveInspectionDocument, resolveInspectionDocument 구현 |
| 2026-02-11 | 상태 분석: Phase 5.1 → 5/6 완료. 결재 워크플로우(5.1.6)만 남음 |

---

*이 문서는 /plan 스킬로 생성되었습니다.*