2026-02-27 09:45:20 +09:00
# 문서 시스템 개선 계획 — 검사 단위 구조 정비
2026-02-27 10:15:19 +09:00
> **⚠️ 이 문서는 아카이브 참조용입니다. 통합 계획은 [`integrated-master-plan.md`](./integrated-master-plan.md)를 참조하세요.**
2026-02-27 09:45:20 +09:00
> **작성일**: 2026-02-26
> **버전**: v2 (리뷰 반영)
> **목적**: 공정별 중간검사 단위(개소별/항목별/수주별) 구조를 정비하고, 하드코딩된 절곡 검사 콘텐츠를 동적 BOM 기반으로 전환
> **기준 문서**: [`document-system-master.md`](./document-system-master.md), [`document-system-mid-inspection.md`](./document-system-mid-inspection.md)
2026-02-27 10:15:19 +09:00
> **상태**: 📦 통합 계획으로 이관 (2026-02-27)
2026-02-27 09:45:20 +09:00
> **관련 계획**: [`product-code-traceability-plan.md`](./product-code-traceability-plan.md) (Phase 1 선행 — product_code 전파 누락 **버그 수정**)
> **리뷰 문서**: [`document-system-improvement-review.md`](./document-system-improvement-review.md) (정책 결정 16건)
---
## 📍 현재 진행 상태
| 항목 | 내용 |
|------|------|
| **마지막 완료 작업** | SuperClaude 페르소나 리뷰 16건 정책 결정 + TemplateInspectionContent bending save/restore 구현 |
| **다음 작업** | Phase 1 - 절곡 BOM 매핑 구조 분석 |
| **진행률** | 0/4 Phase (0%) — 선행 작업 일부 완료 |
| **마지막 업데이트** | 2026-02-27 |
### 선행 완료 커밋 (react/)
| 커밋 | 내용 |
|------|------|
| `7b8b5cf5` | feat: TemplateInspectionContent 절곡 bending save/restore 지원 |
| `54716e63` | feat: InspectionReportModal에서 documentRecords prop 전달 |
| `36052f3e` | fix: bending 개소별 저장 fallback 조건 수정 |
---
## 1. 개요
### 1.1 배경
SAM ERP의 문서 시스템은 mng(양식 관리) → api(데이터 CRUD) → react(동적 렌더링) 3계층으로 구성되어 있다. 중간검사(PQC), 제품검사(FQC), 수입검사(IQC), 작업일지 등의 공장 문서를 처리하며, 현재 Phase 5.1(중간검사) 5/6 완료 상태이다.
**핵심 문제**: 공정별 검사 단위가 통일되지 않아 데이터 구조와 UI 설계에 혼선이 발생하고 있다.
| 공정 | 현재 검사 단위 | 적합한 검사 단위 | GAP |
|------|:------------:|:--------------:|:---:|
| 스크린 | 개소별 (WorkOrderItem당 1행) | 개소별 | ✅ 없음 |
| 슬랫 | 개소별 | 개소별 | ✅ 없음 |
| 조인트바 | 단일행 (슬랫 하위) | 단일행 | ✅ 없음 |
| **절곡** | **하드코딩 7항목 (KWE01 고정)** | **항목별 (BOM 기반 동적)** | ** 🔴 GAP** |
| 절곡 재공품 | 고정값 4항목 | 항목별 | 🟡 GAP |
**3관점 검사 지원 방향** (I3 정책 결정):
- **구성품별**: 절곡의 주 입력 단위. BOM 항목별 검사 (가이드레일, 케이스, 하단마감재 등)
- **개소별**: 부분 출하 시 필요. WorkOrderItem(틀) 단위 검사
- **수주별**: 전체 현황 조회. 수주 소속 전체 개소를 한 문서로 통합 (읽기 전용 뷰)
> 각 관점마다 **작업일지 + 검사 성적서** 보기 지원. 화면 구성·데이터 매핑·UI 설계는 기획자와 별도 협의 후 진행.
### 1.2 용어 정의
| 용어 | 설명 | 예시 |
|------|------|------|
| **개소별 검사** | WorkOrderItem(1틀=1개소) 단위로 1행씩 검사 | 스크린: 10개소 = 10행 |
| **항목별 검사** | 구성품(BOM 항목) 단위로 검사 | 절곡: 가이드레일, 케이스, 하단마감재 등 |
| **수주별 검사** | 수주(Order) 전체를 하나의 검사 단위로 처리 | 50개소 전체를 1문서로 (읽기 전용 뷰) |
| **3관점 검사** | 구성품별/개소별/수주별 세 가지 관점에서 검사 데이터를 조회·입력하는 구조 | 절곡 공정 |
| **INITIAL_PRODUCTS** | BendingInspectionContent.tsx에 하드코딩된 7개 구성품 (**레거시, 동결**) | KWE01 전용 |
| **DEFAULT_GAP_PROFILES** | TemplateInspectionContent.tsx의 구성품별 간격 포인트 기본값 (**Single Source of Truth**) | I1 정책 결정 |
| **BOM** | Bill of Materials, 제품별 구성품 목록 | items 테이블 기반 |
| **EAV** | Entity-Attribute-Value 패턴 (document_data 테이블) | section_id/column_id/row_index/field_key |
| **inspection-config** | 작업지시 ID만으로 공정 타입 + 구성품 목록을 반환하는 범용 API | I5 정책 결정 |
### 1.3 핵심 데이터 흐름 — 검사 문서 생성
```
WorkOrder (작업지시)
├─ process_id → Process (공정)
│ └─ ProcessStep (needs_inspection=true)
│ └─ document_template_id → DocumentTemplate (중간검사 양식)
│
├─ items: WorkOrderItem[] (개소 = 틀)
│ ├─ [0] source_order_item_id → OrderItem → OrderNode.options
│ ├─ [1] ...
│ └─ options: {floor, code, width, height, product_code, ...}
│
└─ Document (중간검사 문서)
├─ linkable_type = 'WorkOrder', linkable_id = work_order_id
├─ template_id → DocumentTemplate
└─ document_data (EAV)
├─ 기본필드: 품명, 규격, LOT NO, 발주처, 현장명 ...
├─ 검사 데이터:
│ ├─ 스크린/슬랫: row_index = 개소, field_key = s{sec}_r{row}_c{col}
│ ├─ 절곡 (TemplateInspectionContent):
│ │ ├─ row_index = 개소 (C1: 스크린/슬랫과 통일)
│ │ └─ field_key = b{productIdx}_ok, b{idx}_p{pt}_n1 등 (구성품 인코딩)
│ └─ 절곡 레거시 (BendingInspectionContent): options.inspection_data JSON
└─ Footer: 부적합내용, 종합판정
데이터 경로 (C2 정책 결정):
├─ Path A: InspectionInputModal → work_order_items.options.inspection_data (개소별 빠른 입력)
└─ Path B: TemplateInspectionContent → document_data EAV (검사 성적서)
→ 두 경로 독립 동작, 마이그레이션 불필요
```
### 1.4 기준 원칙
```
┌─────────────────────────────────────────────────────────────────┐
│ 🎯 핵심 원칙 │
├─────────────────────────────────────────────────────────────────┤
│ 1. 기존 동작 보존: 스크린/슬랫/조인트바 개소별 검사는 건드리지 않음│
│ 2. TemplateInspectionContent 통합: 신규 개발은 여기서 (C3) │
│ 3. BendingInspectionContent 레거시 동결: 유지만, 신규 기능 X (C3)│
│ 4. row_index = 개소 통일: 구성품은 field_key 인코딩 (C1) │
│ 5. EAV 전환 + options 병행: 두 경로 독립 운용 (C2) │
│ 6. 3관점 검사: 구성품별(주입력)/개소별/수주별 지원 (I3) │
│ 7. 롤백 = 템플릿 유무: document_template_id NULL → 레거시 (I4) │
│ 8. 점진적 전환: 레거시/템플릿 모드 병행 유지 │
└─────────────────────────────────────────────────────────────────┘
```
### 1.5 변경 승인 정책
| 분류 | 예시 | 승인 |
|------|------|------|
| ✅ 즉시 가능 | React 컴포넌트 내부 리팩토링, 하드코딩 → API 조회 전환 | 불필요 |
| ⚠️ 컨펌 필요 | API 엔드포인트 추가, document_data 저장 구조 변경, 양식 시더 수정 | **필수** |
| 🔴 금지 | 기존 스크린/슬랫 검사 로직 변경, document_data 스키마 변경 | 별도 협의 |
### 1.6 v2 핵심 변경 사항 (리뷰 반영)
| 정책 | 요약 | 영향 |
|------|------|------|
| **C1** | row_index=개소 통일, 구성품은 field_key 인코딩 | document_data 저장 구조 |
| **C2** | EAV 전환, options 경로 병행 | 마이그레이션 불필요 |
| **C3** | TemplateInspectionContent 통합, BendingInspectionContent 레거시 동결 | Phase 2 방향 전환 |
| **C4** | BOM 동적화 시 스냅샷+식별자 기반 field_key | 추후 Phase |
| **C5** | product_code 전파 누락 = 버그 수정 (fallback 아님) | 선행 의존 |
| **I1** | DEFAULT_GAP_PROFILES 기준 통일 | 5130 대조 후 보정 |
| **I2** | createInspectionDocument에 lockForUpdate+transaction | 별도 작업 |
| **I3** | 3관점(구성품/개소/수주) 지원 | 화면 설계 별도 기획 |
| **I4** | 기각 — 템플릿 유무로 이미 롤백 가능 | 추가 작업 없음 |
| **I5** | `inspection-config` 범용 API (공정 자동 판별) | API 설계 변경 |
| **I6** | 테스트 케이스 보강 | 검증 계획 확대 |
| **I7** | 입력=개소별, 출력=수주별 읽기 전용 뷰 | Phase 4 방향 |
| **M1** | 신규 API에 BelongsToTenant 필수 | SAM 기본 원칙 |
| **M2** | 성공 기준에 API 응답 < 200ms | 성능 지표 추가 |
| **M3** | 마스터 문서 위치 — 구현 시점에 명시 | 추후 |
| **M4** | 타입 통일 불필요 — 레거시 동결, 신규는 TemplateInspectionContent | 추가 작업 없음 |
> 상세 내용: [`document-system-improvement-review.md`](./document-system-improvement-review.md)
---
## 2. 현황 분석
### 2.1 레거시 5130 시스템 분석
5130 시스템은 `output/` 디렉토리에 공정별 문서를 관리한다.
**문서 유형 (5130/output/)**:
| 파일 | 문서 유형 | 검사 단위 | 데이터 저장 |
|------|----------|:--------:|-----------|
| `view_inspection_screen.php` | 스크린 중간검사 | 수주별 | `recordscreen` JSON 컬럼 |
| `view_inspection_slatMid.php` | 슬랫 중간검사 | 수주별 | `recordslatMid` JSON 컬럼 |
| `view_inspection_bending.php` | 절곡 중간검사 | 수주별 | `recordbending` JSON 컬럼 |
| `view_workorder.php` | 작업일지 | 작업지시별 | 전용 테이블 |
| `view_delivery.php` | 납품서 | 수주별 | — |
| `view_inspection_product.php` | 제품검사 | 수주별 | — |
**핵심 발견**:
- 5130에서는 **모든 중간검사가 수주별(per-수주)** 단위
- JSON 컬럼(`recordscreen` , `recordslatMid` , `recordbending` )에 전체 개소 데이터를 한 번에 저장
- 절곡 검사는 구성품 목록이 제품코드(KSS01/KSS02/KWE01)와 마감유형(S1/S2/S3)에 따라 다름
**수입검사 (5130/instock/)**:
- `i_*.php` 형식의 23개 자재별 수입검사 양식
- SAM에서 mng 시더로 이관 완료 (IncomingInspectionTemplateSeeder)
### 2.2 현재 SAM 문서 시스템 — 완성 현황
| 영역 | 상태 | 핵심 파일 | 비고 |
|------|:----:|----------|------|
| mng 양식 관리 (4탭 CRUD) | ✅ | `edit.blade.php` | 기본정보/기본필드/검사기준서/컬럼 |
| mng 문서 상세보기 | ✅ | `show.blade.php` | 검사문서+작업일지 동적 렌더링 |
| API DocumentTemplate 조회 | ✅ | `DocumentTemplateController` | 6모델 Eager Loading |
| API Document CRUD + 결재 | ✅ | `DocumentController` , `DocumentService` | resolve/upsert 패턴 |
| API 중간검사 생성 | ✅ | `WorkOrderService::createInspectionDocument` | 정규화+레거시 형식 지원 |
| API 작업일지 생성/조회 | ✅ | `WorkOrderService::getWorkLog/createWorkLog` | 템플릿 기반 |
| React TemplateInspectionContent | ✅ | 양식 기반 동적 렌더링 + **bending save/restore** | 범용 (통합 방향) |
| React 레거시 검사 콘텐츠 | ✅ | Screen/Slat/Bending*.tsx | 하드코딩 기반 (**동결**) |
| React InspectionInputModal | ✅ | 작업자 화면 검사 입력 | 동적/레거시 병행 |
| React WorkLogModal | ✅ | 작업자 화면 작업일지 | 양식 연동 |
| columns 자동 파생 (방안1) | ✅ | `generateColumnsFromItems()` | 검사기준서→컬럼 자동 |
| 검사기준서↔컬럼 연동 | ✅ | `section_fields` 필수화 | Phase 5.0 |
| 결재 워크플로우 | ⏳ | API ready, 프론트 미연동 | Phase 5.1.6 |
| React 전환 결정 | ⏳ | Phase 4.4 미완료 | 프론트 담당자 협의 필요 |
### 2.3 공정별 검사 구조 상세 분석
#### 스크린 (ScreenInspectionContent) — 개소별 ✅
```
행(row) = WorkOrderItem (개소별 1행)
├─ 검사항목: 가공상태(check), 재봉상태(check), 조립상태(check),
│ 길이(complex), 나비(complex), 간격(check)
├─ 행 수: work_order_items.length (개소 수)
├─ 각 행에 width/height 치수 자동 반영 (WorkOrderItem.options)
└─ mng 양식 ID: 12
```
#### 슬랫 (SlatInspectionContent) — 개소별 ✅
```
행(row) = WorkOrderItem (개소별 1행)
├─ 검사항목: 가공상태(check), 조립상태(check),
│ 높이1(complex), 높이2(complex), 길이(complex)
├─ 행 수: work_order_items.length (개소 수)
└─ mng 양식 ID: 11
```
#### 절곡 — 🔴 동적 전환 필요
```
레거시 (AS-IS) — BendingInspectionContent (동결):
행(row) = INITIAL_PRODUCTS (7개 하드코딩, KWE01 전용)
├─ 가이드레일 벽면형, 가이드레일 측면형, 케이스,
│ 하단마감재, 하단L-BAR, 연기차단재W50, 연기차단재W80
├─ 저장: work_order_items.options.inspection_data (JSON, Path A)
├─ 제품코드별 구성품이 다른데 KWE01만 대응
└─ mng 양식 ID: 13
신규 (TO-BE) — TemplateInspectionContent (C3 통합 방향):
행(row) = WorkOrderItem (개소별), 구성품은 field_key에 인코딩 (C1)
├─ buildBendingProducts()로 동적 구성품 생성 (이미 구현)
├─ DEFAULT_GAP_PROFILES 기준치 사용 (I1: Single Source of Truth)
├─ 저장: document_data EAV (Path B)
│ ├─ row_index = 개소(WorkOrderItem) 인덱스
│ └─ field_key = b{productIdx}_ok, b{idx}_p{pointIdx}_n1 등
├─ API: /work-orders/{id}/inspection-config (I5: 공정 자동 판별)
└─ bending save/restore 구현 완료 (커밋 7b8b5cf5, 36052f3e)
```
#### 3관점 검사 구조 (I3 방향)
```
절곡 공정 검사:
├─ 구성품별 (주 입력): BOM 항목별 검사 데이터 입력
│ ├─ 작업일지: 구성품별 생산 기록
│ └─ 검사 성적서: 구성품별 품질 검사
│
├─ 개소별 (부분 출하): WorkOrderItem 단위 조회+부분 입력
│ ├─ 작업일지: 개소별 작업 기록
│ └─ 검사 성적서: 개소별 검사 현황
│
└─ 수주별 (전체 조회): 수주 소속 전체를 한 문서로 (읽기 전용 뷰)
├─ 작업일지: 수주 전체 작업 현황
└─ 검사 성적서: 수주 전체 검사 현황
※ 화면 구성·데이터 매핑·UI 설계는 기획자와 별도 협의
```
### 2.4 핵심 GAP 상세 — 절곡 INITIAL_PRODUCTS (레거시 동결)
**파일**: `react/src/components/production/WorkOrders/documents/BendingInspectionContent.tsx` (L71-135)
> **C3 정책 결정**: 이 파일은 **레거시로 동결**. 신규 개발은 TemplateInspectionContent에서 진행.
| # | 항목 ID | category | productName | productType | gapPoints 수 |
|---|---------|----------|-------------|-------------|:----------:|
| 1 | guide-rail-wall | KWE01 | 가이드레일 | 벽면형 | 5 |
| 2 | guide-rail-side | KWE01 | 가이드레일 | 측면형 | 5 |
| 3 | case | KWE01 | 케이스 | 500X380 | 4 |
| 4 | bottom-finish | KWE01 | 하단마감재 | 60X40 | 2 |
| 5 | bottom-l-bar | KWE01 | 하단L-BAR | 17X60 | 1 |
| 6 | smoke-w50 | KWE01 | 연기차단재 | W50 가이드레일용 | 2 |
| 7 | smoke-w80 | KWE01 | 연기차단재 | W80 케이스용 | 2 |
**기존 문제** (BendingInspectionContent):
1. KWE01 전용 — 다른 제품코드 미지원
2. 마감유형(S1/S2/S3) 미반영
3. 치수 하드코딩
4. 동적 변경 불가
**해결 방향** (TemplateInspectionContent):
- `buildBendingProducts()` (L209-274)로 동적 구성품 생성 — 이미 구현
- `DEFAULT_GAP_PROFILES` (L176-206)로 기준치 관리
- API에서 BOM 기반 구성품 로딩 시 `buildBendingProducts()` 대체
---
## 3. 대상 범위
### 3.1 Phase 1: 절곡 검사 항목 동적화 기반 구축 ⏳
**목표**: 절곡 구성품(검사 항목) 정보를 API에서 제공하는 구조 마련
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 1.1 | 절곡 제품코드별 구성품(BOM) 데이터 구조 분석 | ⏳ | items/BOM 테이블에서 KWE01/KSS01/KSS02 구성품 확인 |
| 1.2 | 마감유형(S1/S2/S3)별 차이 분석 | ⏳ | 5130 레거시 참조 |
| 1.3 | **inspection-config 범용 API 설계** | ⏳ | `GET /api/v1/work-orders/{id}/inspection-config` (I5) |
| 1.4 | DEFAULT_GAP_PROFILES 기준치 5130 대조 확인 | ⏳ | I1: Single Source of Truth 보정 |
### 3.2 Phase 2: TemplateInspectionContent 절곡 동적 확장 ⏳
**목표**: API 기반 동적 구성품 로딩으로 `buildBendingProducts()` 고정 로직 대체
> **C3 통합 방향**: BendingInspectionContent 대신 TemplateInspectionContent에서 진행
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 2.1 | inspection-config API 구현 (공정 자동 판별) | ⏳ | BelongsToTenant 필수 (M1) |
| 2.2 | TemplateInspectionContent API 연동 (buildBendingProducts 대체) | ⏳ | DEFAULT_GAP_PROFILES → API 기준치 |
| 2.3 | document_data EAV 저장/복원 검증 | ⏳ | C1 field_key 인코딩 패턴 |
| 2.4 | 기존 절곡 검사 데이터 하위 호환 확인 | ⏳ | 레거시(Path A) + 신규(Path B) 독립 동작 |
| 2.5 | createInspectionDocument 트랜잭션 보강 | ⏳ | I2: lockForUpdate + DB::transaction |
### 3.3 Phase 3: 절곡 재공품 양식 + 기타 정비 ⏳
**목표**: 절곡 재공품(BendingWip) 검사 양식 추가, 결재 워크플로우 연동
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 3.1 | 절곡 재공품 mng 양식 시더 추가 (또는 절곡 양식 통합) | ⏳ | BendingWipInspectionContent 대응 |
| 3.2 | 결재 워크플로우 프론트 연동 (Phase 5.1.6) | ⏳ | 작성→검토→승인 3단계 |
| 3.3 | Phase 4.4 — React 기존 하드코딩 컴포넌트 전환 결정 | ⏳ | 프론트 담당자 협의 |
### 3.4 Phase 4: 3관점 검사 + 수주별 뷰 설계 (추후) ⏭️
**목표**: 구성품별/개소별/수주별 3관점 검사 구조 설계 및 수주별 읽기 전용 뷰 구현
> **⚠️ Phase 2 완료 후 별도 일정. 화면 설계는 기획자와 협의 필요.**
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 4.1 | 3관점 검사 데이터 모델 상세 설계 | ⏭️ | 구성품별↔개소별↔수주별 매핑 (I3) |
| 4.2 | 수주별 읽기 전용 뷰 설계 | ⏭️ | 입력=개소별, 출력=수주별 (I7) |
| 4.3 | 5130 recordscreen JSON → EAV 변환 규칙 | ⏭️ | 이관 설계 |
| 4.4 | 기획자 협의 — 화면 구성, UI/UX | ⏭️ | 3관점 각각의 화면 레이아웃 |
---
## 4. 상세 작업 내용
### 4.1 Phase 1 상세: 절곡 검사 항목 동적화 기반
#### 4.1.1 절곡 구성품 데이터 소스 분석
현재 제품별 구성품(BOM)이 어디에 정의되어 있는지 확인 필요:
```
분석 대상:
1. items 테이블 — type='finished_goods' 또는 'component'인 항목
2. bom_items 테이블 — 제품→구성품 관계
3. order_nodes.options.bending_info — 수주 시 절곡 정보
4. 5130/estimate/common/common_addrowJS.php — 레거시 구성품 정의
5. mng 절곡 양식(ID:13)의 section_items — 검사기준서 항목
6. TemplateInspectionContent DEFAULT_GAP_PROFILES — 현재 기준치 (I1)
```
#### 4.1.2 구성품 결정 로직 (설계안)
```
입력: work_order_id
↓
1차: 작업지시 → 공정 자동 판별 (inspection-config API)
↓
2차: product_code → BOM 테이블에서 하위 구성품 조회
↓ (BOM 미등록 시)
3차: DEFAULT_GAP_PROFILES 기본값 사용 (TemplateInspectionContent)
↓ (템플릿 미설정 시 = 레거시)
4차: INITIAL_PRODUCTS fallback (BendingInspectionContent, KWE01 하위호환)
```
#### 4.1.3 API 설계안 (I5 정책 결정 반영)
```
GET /api/v1/work-orders/{id}/inspection-config
※ BelongsToTenant 스코프 필수 적용 (M1)
※ 공정 타입 자동 판별 — 프론트에서 공정 하드코딩 불필요
Response:
{
"data": {
"work_order_id": 123,
"process_type": "bending", // 자동 판별
"product_code": "FG-KQTS01",
"finish_type": "S1",
"template_id": 60,
"items": [
{
"id": "guide-rail-wall",
"category": "KWE01",
"product_name": "가이드레일",
"product_type": "벽면형",
"length_design": "3000",
"width_design": "N/A",
"gap_points": [
{ "point": "①", "design_value": "30" },
{ "point": "②", "design_value": "78" },
...
]
},
...
]
}
}
비절곡 공정 Response (스크린/슬랫):
{
"data": {
"work_order_id": 456,
"process_type": "screen",
"product_code": "FG-KQTS01",
"template_id": 12,
"items": [] // 비절곡은 구성품 목록 불필요
}
}
```
### 4.2 Phase 2 상세: TemplateInspectionContent 절곡 동적 확장
#### 4.2.1 현재 코드 구조 (TemplateInspectionContent — 이미 구현된 부분)
```typescript
// TemplateInspectionContent.tsx
// 구성품 간격 기준치 (I1: Single Source of Truth)
const DEFAULT_GAP_PROFILES = { /* L176-206 */ };
// 동적 구성품 생성 (order.bendingInfo 기반)
function buildBendingProducts(order): BendingProduct[] { /* L209-274 */ }
// bending 감지
const isBending = order.processType === 'bending' || columns에 point sub_labels 존재;
// bending save: field_key = b{idx}_ok, b{idx}_p{pt}_n1 등
// bending restore: documentRecords에서 field_key 패턴 매칭으로 복원
```
#### 4.2.2 변경 방향 (TO-BE)
```typescript
// TemplateInspectionContent.tsx (Phase 2 변경)
// AS-IS: buildBendingProducts()가 order.bendingInfo에서 고정 로직으로 구성품 생성
// TO-BE: inspection-config API에서 BOM 기반 구성품 목록 수신
interface InspectionConfig {
process_type: string;
product_code: string;
items: BendingInspectionItem[]; // API에서 수신
}
// 컴포넌트 내부
const configItems = useInspectionConfig(workOrderId); // API 호출
const bendingProducts = configItems ?? buildBendingProducts(order); // fallback
```
#### 4.2.3 document_data 저장 구조 (C1 정책 결정 반영)
```
row_index 의미: 모든 공정에서 "개소(WorkOrderItem)" 통일 (C1)
스크린/슬랫 (기존):
row_index = WorkOrderItem 인덱스 (0, 1, 2, ...)
field_key = s{section}_r{row}_c{column}_sub{index}
절곡 — TemplateInspectionContent (C1 인코딩 패턴):
row_index = WorkOrderItem 인덱스 (개소) — 스크린/슬랫과 동일
field_key 패턴:
├─ b{productIdx}_ok → 구성품 OK/NG 판정
├─ b{productIdx}_ng → NG 상세
├─ b{productIdx}_value → 길이/너비 측정값
├─ b{productIdx}_judgment → 종합 판정
├─ b{productIdx}_p{pointIdx}_n1 → 간격 포인트 측정값 1
├─ b{productIdx}_p{pointIdx}_n2 → 간격 포인트 측정값 2
└─ b{productIdx}_n{n} → 추가 측정값
※ 이미 TemplateInspectionContent save/restore에 구현 완료 (커밋 7b8b5cf5)
※ productIdx는 buildBendingProducts() 반환 배열의 인덱스
BOM 동적화 시 (C4 추후):
├─ field_key → b{productId}_... 형태로 전환 (순서 독립적)
├─ document.options에 bom_snapshot 저장
└─ 인덱스 기반 → 식별자 기반 매핑
```
**하위호환 (C2)**:
- 기존 절곡 검사 데이터는 `work_order_items.options.inspection_data` (Path A)에 저장
- 신규 데이터는 `document_data` EAV (Path B)에 저장
- 두 경로가 독립적으로 동작하므로 마이그레이션 불필요
### 4.3 Phase 4 구조 설계 — 3관점 검사 + 수주별 뷰
#### 4.3.1 3관점 검사 모델 (I3 정책 결정)
```
구성품별 (주 입력):
├─ 단위: BOM 항목 (가이드레일, 케이스, 하단마감재 등)
├─ 입력: 구성품별 OK/NG, 측정값, 간격 포인트
├─ 화면: 작업일지 + 검사 성적서
└─ 데이터: document_data EAV (field_key 인코딩)
개소별 (부분 출하):
├─ 단위: WorkOrderItem (1틀=1개소)
├─ 입력: 개소별 검사 데이터 조회 + 부분 입력 가능
├─ 화면: 작업일지 + 검사 성적서
└─ 데이터: row_index로 필터링
수주별 (전체 조회 — I7):
├─ 단위: 수주(Order) 전체
├─ 입력: 읽기 전용 뷰 (입력은 개소별에서)
├─ 화면: 작업일지 + 검사 성적서 통합 조회
└─ 데이터: 여러 WorkOrder의 document_data 통합 렌더링
※ 화면 구성·데이터 매핑·UI 설계는 기획자와 별도 협의
```
#### 4.3.2 수주별 읽기 전용 뷰 (I7 정책 결정)
```
수주별 뷰 설계 방향:
├─ 입력은 개소별 (현행 워크플로우 유지)
├─ 수주별은 읽기 전용 통합 조회
├─ 기존 per-개소 Document 데이터를 수주 단위로 합산 렌더링
├─ 별도 수주별 Document 생성 불필요 (뷰 레벨 통합)
└─ 데이터 중복 없음
구현 방안:
├─ 수주 ID → 소속 WorkOrder 목록 조회
├─ 각 WorkOrder의 Document.document_data 수집
├─ 통합 렌더링 (개소 순서대로)
└─ 인쇄 시 수주별 양식으로 출력
```
---
## 5. DB 관계도 — 문서 시스템 전체
```
document_templates (양식 마스터)
├── sections → section_items (검사기준서 항목)
├── columns (테이블 컬럼 정의, 자동 파생 가능)
├── basic_fields (기본필드: 품명, LOT NO 등)
├── section_fields (동적 필드 정의)
├── approval_lines (결재라인)
├── field_presets (필드 프리셋)
└── links (외부 키 매핑)
documents (문서 인스턴스)
├── template_id → document_templates
├── linkable_type + linkable_id (polymorphic)
│ ├── WorkOrder (중간검사: per-작업지시, 내부 per-개소 행)
│ ├── OrderItem (제품검사: per-개소)
│ ├── Material (수입검사: per-자재)
│ └── Order (수주별 검사: per-수주, 추후 — 뷰 레벨 통합 우선 I7)
├── document_data (EAV: section_id/column_id/row_index/field_key/field_value)
│ └── 절곡 field_key: b{productIdx}_ok, b{idx}_p{pt}_n1 등 (C1)
├── document_approvals (결재 상태)
└── document_attachments (첨부파일)
process_steps
├── document_template_id → 공정별 검사 양식 매핑
│ └── NULL이면 레거시 컴포넌트 사용 (I4: 롤백 메커니즘)
└── needs_inspection = true
work_orders
├── items: work_order_items[]
│ ├── options JSON: {floor, code, width, height, product_code, ...}
│ │ └── product_code: product-code-traceability-plan Phase 1에서 버그 수정 (C5)
│ ├── source_order_item_id → order_items
│ └── 검사 데이터 저장 경로:
│ ├── Path A: options.inspection_data (InspectionInputModal, 개소별)
│ └── Path B: document_data EAV (TemplateInspectionContent, 검사 성적서)
└── documents (morphMany) — 중간검사/작업일지
```
---
## 6. 5130 레거시 문서 참조표
### 6.1 중간검사 문서 (5130/output/)
| 레거시 파일 | SAM 양식 ID | SAM 컴포넌트 | 전환 상태 |
|------------|:---------:|-------------|:--------:|
| `view_inspection_screen.php` | 12 | ScreenInspectionContent | ✅ |
| `view_inspection_slatMid.php` | 11 | SlatInspectionContent | ✅ |
| — (조인트바는 슬랫 하위) | 10 | SlatJointBarInspectionContent | ✅ |
| `view_inspection_bending.php` | 13 | ~~BendingInspectionContent~~ → **TemplateInspectionContent** | 🔄 동적 확장 중 |
| — | — | BendingWipInspectionContent | ⏳ 양식 미존재 |
### 6.2 기타 문서 (5130/output/)
| 레거시 파일 | SAM 대응 | 상태 |
|------------|---------|:----:|
| `view_workorder.php` | WorkLogModal/Content | ✅ Phase 5.3 |
| `view_delivery.php` | 납품서 (미착수) | ⏭️ |
| `view_inspection_product.php` | ProductInspectionDocument | ✅ Phase 5.2 |
### 6.3 수입검사 (5130/instock/)
- 23개 자재별 양식 (`i_*.php` ) → mng IncomingInspectionTemplateSeeder로 이관
- 상세: [`incoming-inspection-templates-plan.md` ](./incoming-inspection-templates-plan.md )
---
## 7. 컨펌 대기 목록
| # | 항목 | 변경 내용 | 영향 범위 | 상태 |
|---|------|----------|----------|------|
| 1 | Phase 1 실행 승인 | 절곡 구성품 데이터 소스 분석 + API 설계 | 분석만, 코드 변경 없음 | ⚠️ 대기 |
| 2 | ~~절곡 구성품 로딩 방식~~ | ~~BOM 기반 vs 양식 내 구성품 템플릿~~ | — | ✅ C3에서 결정 |
| 3 | ~~절곡 재공품 양식 방향~~ | ~~별도 양식 신규 vs 절곡 양식 통합~~ | — | ⏳ Phase 3 |
| 4 | ~~수주별 검사 방향~~ | ~~Option A/B/C~~ | — | ✅ I7에서 결정 |
| 5 | 3관점 검사 화면 설계 | 구성품별/개소별/수주별 UI/UX | 기획자 협의 필요 | ⏭️ Phase 4 |
---
## 8. 작업 절차 요약
```
선행: product-code-traceability-plan Phase 1 완료 (C5: product_code 전파 버그 수정)
선행: createInspectionDocument 트랜잭션 보강 (I2: lockForUpdate + DB::transaction)
↓
Phase 1 (기반 구축) ─── 분석 + 설계, 코드 변경 최소
├── Step 1: items/BOM 테이블에서 절곡 구성품 데이터 분석
├── Step 2: KWE01/KSS01/KSS02별 구성품 차이 파악
├── Step 3: DEFAULT_GAP_PROFILES 기준치 5130 대조 (I1)
└── Step 4: inspection-config 범용 API 설계 (I5) → 컨펌
Phase 2 (TemplateInspectionContent 동적 확장) ─── 핵심 구현 (C3)
├── Step 1: inspection-config API 구현 (BelongsToTenant 필수 M1)
├── Step 2: TemplateInspectionContent buildBendingProducts → API 연동
├── Step 3: document_data EAV 저장/복원 검증 (C1 field_key)
├── Step 4: 레거시(Path A) + 신규(Path B) 독립 동작 확인 (C2)
└── Step 5: 기존 데이터 정상 표시 확인
Phase 3 (정비) ─── 기타 미완료 항목
├── Step 1: 절곡 재공품 양식 추가
├── Step 2: 결재 워크플로우 프론트 연동
└── Step 3: Phase 4.4 협의 (React 전환 결정)
Phase 4 (3관점 검사 + 수주별 뷰) ─── 기획자 협의 후 진행 ⏭️
├── Step 1: 기획자와 3관점 화면 설계 협의 (I3)
├── Step 2: 수주별 읽기 전용 뷰 구현 (I7)
└── Step 3: 개소별↔구성품별↔수주별 데이터 매핑
```
---
## 9. 성공 기준
| 기준 | 측정 방법 | 수치 목표 |
|------|----------|----------|
| 절곡 검사 구성품 동적 로딩 | KWE01, KSS01, KSS02 제품코드별 다른 구성품 표시 | 3종 이상 지원 |
| 마감유형별 구성품 차이 반영 | S1/S2/S3 마감유형 선택 시 구성품 변경 | 정상 변경 |
| 기존 절곡 검사 데이터 호환 | 기저장 KWE01 검사 데이터 정상 조회 (Path A + Path B) | 100% 호환 |
| ~~INITIAL_PRODUCTS 하드코딩 제거~~ | ~~BendingInspectionContent에서 하드코딩 상수 미사용~~ | C3: 레거시 동결 |
| TemplateInspectionContent 동적화 | buildBendingProducts → API 기반 구성품 로딩 | 완전 전환 |
| 스크린/슬랫 검사 회귀 없음 | 기존 개소별 검사 정상 동작 | 에러 0건 |
| document_data 저장 정합성 | C1 field_key 인코딩 저장/조회 일치 | 100% |
| **inspection-config API 응답 성능** | **구성품 목록 API 응답 시간** | ** < 200ms ( M2 )** |
---
## 10. 핵심 파일 경로
### React (절곡 검사 관련)
| 파일 | 역할 | 주요 라인 | v2 상태 |
|------|------|----------|:------:|
| `react/.../documents/TemplateInspectionContent.tsx` | 양식 기반 동적 렌더링 + **bending save/restore** | L176-274 DEFAULT_GAP_PROFILES, buildBendingProducts | **통합 방향 (C3)** |
| `react/.../documents/BendingInspectionContent.tsx` | 절곡 중간검사 성적서 | L71-135 INITIAL_PRODUCTS | **레거시 동결 (C3)** |
| `react/.../documents/BendingWipInspectionContent.tsx` | 절곡 재공품 검사 | — | Phase 3 |
| `react/.../documents/InspectionReportModal.tsx` | 중간검사 모달 (래퍼) | L386-418 activeTemplate 분기 | documentRecords 전달 완료 |
| `react/.../documents/inspection-shared.tsx` | 공유 유틸/컴포넌트 | — | — |
| `react/.../WorkerScreen/InspectionInputModal.tsx` | 작업자 화면 검사 입력 | ~950행 | Path A (options) 유지 |
| `react/.../documents/ScreenInspectionContent.tsx` | 스크린 중간검사 (참조용) | 개소별 패턴 | 변경 없음 |
| `react/.../documents/SlatInspectionContent.tsx` | 슬랫 중간검사 (참조용) | 개소별 패턴 | 변경 없음 |
### API
| 파일 | 역할 | 주요 메서드 | v2 비고 |
|------|------|-----------|--------|
| `api/app/Services/WorkOrderService.php` | 검사 문서 생성/조회 | createInspectionDocument, resolveInspectionDocument | I2: 트랜잭션 보강 필요 |
| `api/app/Services/DocumentService.php` | 문서 CRUD | create, update, formatTemplateForReact, resolve, upsert | — |
| `api/app/Http/Controllers/V1/DocumentController.php` | 문서 API | — | — |
| `api/app/Models/Documents/Document.php` | 문서 모델 | linkable morphTo, data() HasMany | — |
### mng
| 파일 | 역할 |
|------|------|
| `mng/database/seeders/MidInspectionTemplateSeeder.php` | 중간검사 양식 시더 (4종) |
| `mng/resources/views/document-templates/edit.blade.php` | 양식 편집 UI |
| `mng/resources/views/documents/show.blade.php` | 문서 상세보기 |
### 5130 레거시 (참조용)
| 파일 | 역할 |
|------|------|
| `5130/output/view_inspection_bending.php` | 절곡 중간검사 성적서 |
| `5130/output/_row.php` | output 테이블 구조 (recordbending JSON) |
| `5130/estimate/common/common_addrowJS.php` | 제품별 구성품 정의 로직 |
---
## 11. 변경 이력
| 날짜 | 항목 | 변경 내용 | 파일 | 승인 |
|------|------|----------|------|------|
| 2026-02-26 | 문서 초안 (v1) | 4개 분석 에이전트 결과 종합, 계획 수립 | - | - |
| 2026-02-26 | bending save/restore | TemplateInspectionContent 절곡 저장/복원 구현 | react/ 3건 커밋 | ✅ |
| 2026-02-27 | 리뷰 정책 결정 | SuperClaude 페르소나 리뷰 16건 전체 완료 | review.md | ✅ |
| 2026-02-27 | **v2 반영** | 16건 정책 결정 계획서 반영: C3 통합 방향, C1 field_key 인코딩, I5 inspection-config API, I3 3관점 검사, I7 수주별 읽기 전용 뷰, M2 성능 기준 등 | plan.md | - |
---
## 12. 세션 및 메모리 관리 정책
### 12.1 세션 시작 시
```
1. 이 문서(document-system-improvement-plan.md) 읽기
2. 진행 상태 테이블 확인 → 마지막 완료 작업 파악
3. 리뷰 문서(document-system-improvement-review.md) 정책 결정 확인
4. 마스터 문서(document-system-master.md) 현행 Phase 상태 확인
5. 다음 작업 시작
```
### 12.2 작업 중 관리
- Phase 완료 시 이 문서의 상태 테이블 업데이트
- 마스터 문서(document-system-master.md)도 동기화 업데이트 (M3)
- 컨펌 필요 사항 발생 시 컨펌 대기 목록에 추가
### 12.3 세션 종료 시
- 변경 이력 섹션에 최종 업데이트 기록
---
## 13. 검증 결과
> 작업 완료 후 이 섹션에 검증 결과 추가
### 13.1 Phase 1 검증
| 조사 항목 | 결과 | 판단 |
|----------|------|------|
| KWE01 BOM 구성품 수 | | ⏳ |
| KSS01 BOM 구성품 수 | | ⏳ |
| KSS02 BOM 구성품 수 | | ⏳ |
| 마감유형별 차이점 | | ⏳ |
| DEFAULT_GAP_PROFILES 5130 대조 (I1) | | ⏳ |
### 13.2 Phase 2 검증
| 테스트 | 예상 결과 | 실제 결과 | 상태 |
|--------|----------|----------|------|
| KWE01 제품코드 → 구성품 표시 | buildBendingProducts 결과와 동일 | | ⏳ |
| KSS01 제품코드 → 다른 구성품 표시 | KSS01 전용 구성품 | | ⏳ |
| KSS02 제품코드 → 다른 구성품 표시 | KSS02 전용 구성품 | | ⏳ |
| 마감유형 S1/S2/S3 각각 | 유형별 구성품 차이 반영 | | ⏳ |
| 구성품 수 7개 미만/초과 | 정상 렌더링 | | ⏳ |
| API 미응답 시 fallback | buildBendingProducts 기본값 사용 | | ⏳ |
| BOM 미등록 시 | DEFAULT_GAP_PROFILES 기본값 사용 | | ⏳ |
| API 타임아웃 시 | 에러 처리 + fallback | | ⏳ |
| 빈 배열 반환 시 | 빈 테이블 or fallback | | ⏳ |
| 저장→조회→재저장 사이클 | 데이터 무손실 | | ⏳ |
| 기존 절곡 검사 데이터 조회 (Path A) | 정상 표시 (레거시 경로) | | ⏳ |
| 신규 절곡 검사 데이터 저장/조회 (Path B) | EAV 정상 동작 | | ⏳ |
| mng show.blade.php 렌더링 | 검사 성적서 정상 표시 | | ⏳ |
| 인쇄 레이아웃 | 양식에 맞는 인쇄 출력 | | ⏳ |
| inspection-config API 응답 시간 | < 200ms | | ⏳ |
| 스크린/슬랫 검사 회귀 | 변화 없음 | | ⏳ |
| 트랜잭션 동시 접근 (I2) | race condition 없음 | | ⏳ |
### 13.3 Phase 3 검증
| 테스트 | 예상 결과 | 실제 결과 | 상태 |
|--------|----------|----------|------|
| 절곡 재공품 양식 정상 동작 | 양식 편집/미리보기 OK | | ⏳ |
| 결재 워크플로우 3단계 | 작성→검토→승인 | | ⏳ |
---
## 14. 자기완결성 점검 결과
### 14.1 체크리스트 검증
| # | 검증 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 1 | 작업 목적이 명확한가? | ✅ | 절곡 항목별 검사 동적화 + 3관점 검사 구조 (I3) |
| 2 | 성공 기준이 정의되어 있는가? | ✅ | 섹션 9 - 성능 지표 포함 (M2) |
| 3 | 작업 범위가 구체적인가? | ✅ | Phase 1-3 구현, Phase 4 설계 |
| 4 | 의존성이 명시되어 있는가? | ✅ | C5 버그 수정, I2 트랜잭션 보강 |
| 5 | 참고 파일 경로가 정확한가? | ✅ | v2 상태 컬럼 추가 |
| 6 | 단계별 절차가 실행 가능한가? | ✅ | API 설계안 + 코드 변경 방향 포함 |
| 7 | 검증 방법이 명시되어 있는가? | ✅ | I6 보강 테스트 케이스 포함 |
| 8 | 모호한 표현이 없는가? | ✅ | 용어 정의 확대, 정책 결정 근거 명시 |
### 14.2 새 세션 시뮬레이션 테스트
| 질문 | 답변 가능 | 참조 섹션 |
|------|:--------:|----------|
| Q1. 이 작업의 목적은 무엇인가? | ✅ | 1.1 배경 |
| Q2. 어디서부터 시작해야 하는가? | ✅ | 3.1 Phase 1 + 8. 작업 절차 |
| Q3. 어떤 파일을 수정해야 하는가? | ✅ | 10. 핵심 파일 경로 (v2 상태 포함) |
| Q4. 작업 완료 확인 방법은? | ✅ | 9. 성공 기준 + 13. 검증 결과 |
| Q5. 막혔을 때 참고 문서는? | ✅ | 마스터 문서 + 리뷰 문서 + 10. 파일 경로 |
| Q6. 리뷰 정책 결정은 어디서 확인하나? | ✅ | 1.6 핵심 변경 사항 + 리뷰 문서 링크 |
| Q7. 기존 검사에 영향이 있는가? | ✅ | 1.4 기준 원칙 #1 , I4 롤백 메커니즘 |
| Q8. 두 데이터 경로(Path A/B)는 어떻게 동작하는가? | ✅ | 1.3 데이터 흐름 + 4.2.3 저장 구조 |
---
## 15. 참고 문서
| 문서 | 경로 | 용도 |
|------|------|------|
| 문서 시스템 마스터 | `docs/plans/document-system-master.md` | 전체 Phase 진행 관리 |
| **리뷰 정책 결정** | `docs/plans/document-system-improvement-review.md` | **16건 정책 결정 상세** |
| 중간검사 계획 | `docs/plans/document-system-mid-inspection.md` | Phase 5.1 상세 |
| 작업일지 계획 | `docs/plans/document-system-work-log.md` | Phase 5.3 상세 |
| 제품코드 추적성 | `docs/plans/product-code-traceability-plan.md` | product_code 전파 버그 수정 (C5 선행) |
| 수입검사 양식 | `docs/plans/incoming-inspection-templates-plan.md` | 23개 양식 이관 |
| DB 스키마 | `docs/specs/database-schema.md` | 테이블 구조 |
| mng 규칙 | `mng/CLAUDE.md` | mng 프로젝트 규칙 |
| API 규칙 | `API_RULES.md` | Service-First, FormRequest |
---
*이 문서는 /plan 스킬로 생성되었습니다. v2: SuperClaude 페르소나 리뷰 16건 정책 결정 반영 (2026-02-27)*