# 문서관리 시스템 개발 계획

> **작성일**: 2026-01-31
> **목적**: mng에서 문서양식(템플릿)을 관리하고 문서를 생성하여, SAM(react)에서 JSON으로 소비하는 문서관리 시스템을 구축한다
> **기준 문서**: `docs/specs/database-schema.md`, `mng/CLAUDE.md`
> **상태**: 📋 계획 확정 → Phase 1 시작 대기

---

## 🚀 새 세션 시작 가이드

> **이 섹션은 새 세션에서 이 문서만 보고 작업을 시작할 수 있도록 작성되었습니다.**

### 프로젝트 정보

| 항목 | 내용 |
|------|------|
| **작업 프로젝트** | `mng` (관리자 패널) |
| **절대 경로** | `/Users/kent/Works/@KD_SAM/SAM/mng/` |
| **기술 스택** | Laravel 12 + Plain Blade + DaisyUI + HTMX + Alpine.js |
| **로컬 URL** | `https://mng.sam.kr` (Docker 로컬, `admin.sam.kr`도 동일) |
| **관련 API** | `/Users/kent/Works/@KD_SAM/SAM/api/` (Laravel 12 REST API) |
| **프론트** | `/Users/kent/Works/@KD_SAM/SAM/react/` (Next.js 15, 이 작업에서는 미수정) |
| **5130 레거시** | `/Users/kent/Works/@KD_SAM/SAM/5130/` (참조 전용) |
| **문서 경로** | `/Users/kent/Works/@KD_SAM/SAM/docs/` |

### mng Git 저장소

```bash
cd /Users/kent/Works/@KD_SAM/SAM/mng
git status && git branch
```

> **주의**: SAM/ 루트는 Git 저장소가 아님. api/, mng/, react/ 각각 독립 Git 저장소.

### 세션 시작 체크리스트

```
1. 이 문서를 읽는다 (📍 현재 진행 상태 섹션 확인)
2. mng/CLAUDE.md 를 읽는다 (mng 프로젝트 규칙 확인)
3. 마지막 완료 작업 확인 → 다음 작업 결정
4. 해당 Phase의 상세 절차(섹션 11)를 읽는다
5. 작업 시작 전 사용자에게 "Phase X.X 시작할까요?" 확인
```

### 핵심 파일 (작업 빈도순)

| 파일 | 설명 | 크기 |
|------|------|------|
| `mng/resources/views/document-templates/edit.blade.php` | 양식 편집 UI (메인 작업 대상) | 44.5KB |
| `mng/app/Http/Controllers/DocumentTemplateController.php` | 양식 CRUD 컨트롤러 | |
| `mng/app/Http/Controllers/DocumentController.php` | 문서 CRUD 컨트롤러 | |
| `mng/app/Models/DocumentTemplate.php` | 양식 모델 (관계 정의) | |
| `mng/app/Models/Documents/Document.php` | 문서 모델 (상태 워크플로우) | |
| `mng/routes/web.php` (340-353줄) | 양식/문서 라우트 | |

### 모델 관계 구조 (코드 참조)

```php
// DocumentTemplate.php 주요 관계
class DocumentTemplate extends Model {
    use BelongsToTenant, SoftDeletes;

    // 결재라인: template->approval_lines (작성/검토/승인)
    public function approvalLines() { return $this->hasMany(DocumentTemplateApprovalLine::class, 'template_id')->orderBy('sort_order'); }

    // 기본필드: template->basic_fields (품명, LOT NO 등)
    public function basicFields() { return $this->hasMany(DocumentTemplateBasicField::class, 'template_id')->orderBy('sort_order'); }

    // 섹션: template->sections->items (검사기준서 섹션 + 검사항목)
    public function sections() { return $this->hasMany(DocumentTemplateSection::class, 'template_id')->orderBy('sort_order'); }

    // 컬럼: template->columns (데이터 테이블 컬럼 정의)
    public function columns() { return $this->hasMany(DocumentTemplateColumn::class, 'template_id')->orderBy('sort_order'); }
}

// Document.php 주요 관계
class Document extends Model {
    use BelongsToTenant, SoftDeletes;

    // 상태: DRAFT -> PENDING -> APPROVED/REJECTED/CANCELLED
    protected $casts = ['status' => DocumentStatus::class];

    public function template() { return $this->belongsTo(DocumentTemplate::class); }
    public function approvals() { return $this->hasMany(DocumentApproval::class); }
    public function data() { return $this->hasMany(DocumentData::class); }         // EAV 패턴
    public function attachments() { return $this->hasMany(DocumentAttachment::class); }
    public function linkable() { return $this->morphTo(); }  // 다형성 연결 (수주, 작업지시 등)
}
```

### mng 라우트 구조

```php
// mng/routes/web.php (340-353줄)
Route::resource('document-templates', DocumentTemplateController::class);  // /document-templates
Route::resource('documents', DocumentController::class);                   // /documents
```

> **URL 확인**: `https://mng.sam.kr/document-templates` (양식 관리), `https://mng.sam.kr/documents` (문서 관리)

---

## 📍 현재 진행 상태

| 항목 | 내용 |
|------|------|

| **마지막 완료 작업** | Phase 4.2 - mng JSON 기반 문서 화면 구현 (show.blade.php 섹션 테이블 + Footer) |
| **다음 작업** | Phase 4.3 - mng에서 문서 데이터 입력/저장 연동 |
| **진행률** | 15/20 (75%) - Phase 1 ✅, Phase 2 ✅, Phase 3 ✅, Phase 4.1-4.2 ✅ |
| **마지막 업데이트** | 2026-01-31 |

---

## 1. 개요

### 1.1 배경

현재 SAM(react)에는 검사 성적서(수입검사, 중간검사), 작업일지 등이 하드코딩된 모달 컴포넌트로 존재한다. 5130 레거시 시스템에도 동일 문서들이 PHP 파일 단위로 구현되어 있다. 이들을 **mng에서 동적으로 양식을 관리**하고, **API를 통해 JSON으로 제공**하여 SAM에서 렌더링하는 구조로 전환한다.

**핵심 문제:**
- 현재 검사 문서가 React 컴포넌트에 하드코딩되어, 새 양식 추가 시 코드 수정이 필요
- 5130의 수입검사만 약 40종의 자재별 페이지가 개별 PHP 파일로 존재
- 검사 기준, 항목, 판정 로직이 코드와 혼재되어 비개발자가 관리 불가
- 중간검사(절곡/스크린/슬랫/조인트바)도 각각 별도 컴포넌트로 분산

**해결 방향:**
- mng에서 문서양식(템플릿)을 동적으로 정의 → 검사 항목/기준/판정 로직 포함
- 양식 기반으로 실제 문서 인스턴스를 생성 → 데이터 입력/결재/출력
- SAM에서 API로 양식+데이터를 JSON 수신 → 범용 렌더러로 표시

### 1.2 기준 원칙

```
┌─────────────────────────────────────────────────────────────────┐
│  핵심 원칙                                                       │
├─────────────────────────────────────────────────────────────────┤
│  1. 양식 정의는 mng에서만 관리 (비개발자도 양식 수정 가능하도록)   │
│  2. SAM(react)은 JSON을 받아 렌더링만 담당 (문서 로직 없음)       │
│  3. 기존 DB 구조(document_templates 계열) 최대한 활용             │
│  4. 5130 레거시의 검사 기준/항목을 데이터로 이관                  │
│  5. 결재 워크플로우(DRAFT->PENDING->APPROVED) 유지                │
└─────────────────────────────────────────────────────────────────┘
```

### 1.3 변경 승인 정책

| 분류 | 예시 | 승인 |
|------|------|------|
| 즉시 가능 | 양식 필드 추가/변경, 검사항목 추가, 기준값 수정, 뷰(Blade) 수정 | 불필요 |
| 컨펌 필요 | 새 DB 테이블 추가, 기존 테이블 컬럼 변경, API 엔드포인트 추가, 마이그레이션 | **필수** |
| 금지 | 기존 document_templates 테이블 구조 파괴적 변경, 기존 API 삭제 | 별도 협의 |

### 1.4 준수 규칙
- `docs/specs/database-schema.md` - DB 스키마 참조
- `docs/standards/quality-checklist.md` - 품질 체크리스트
- `mng/CLAUDE.md` - MNG 프로젝트 규칙

---

## 2. 현황 분석

### 2.1 기존 DB 구조 (이미 생성됨)

```
document_templates                    # 양식 마스터
├── document_template_approval_lines  # 결재라인 (작성/검토/승인)
├── document_template_basic_fields    # 기본필드 (품명, LOT NO 등)
├── document_template_sections        # 섹션 (검사기준서 섹션)
│   └── document_template_section_items # 섹션 항목 (검사항목)
└── document_template_columns         # 데이터 테이블 컬럼

documents                             # 문서 인스턴스
├── document_approvals                # 결재 이력
├── document_data                     # 필드 데이터 (EAV 패턴)
└── document_attachments              # 첨부 파일
```

**주요 테이블 컬럼:**

| 테이블 | 핵심 컬럼 |
|--------|----------|
| `document_templates` | tenant_id, name, category, title, company_name, footer_remark_label, footer_judgement_label, footer_judgement_options(json) |
| `document_template_approval_lines` | template_id, name, dept, role, sort_order |
| `document_template_basic_fields` | template_id, label, field_type(text/date), default_value, sort_order |
| `document_template_sections` | template_id, title, image_path, sort_order |
| `document_template_section_items` | section_id, category, item, standard, method, frequency, regulation, sort_order |
| `document_template_columns` | template_id, label, column_type(text/check/measurement/select/complex), group_name, sub_labels(json), width, sort_order |
| `documents` | tenant_id, template_id, document_no, title, status(DRAFT/PENDING/APPROVED/REJECTED/CANCELLED), linkable_type, linkable_id |
| `document_data` | document_id, section_id, column_id, row_index, field_key, field_value |
| `document_approvals` | document_id, user_id, step, role, status(PENDING/APPROVED/REJECTED), comment, acted_at |

### 2.2 기존 MNG 코드 현황

| 항목 | 경로 | 상태 |
|------|------|------|
| DocumentTemplate 모델 | `mng/app/Models/DocumentTemplate.php` | 존재 |
| Document 모델 | `mng/app/Models/Documents/Document.php` | 존재 |
| 관련 하위 모델 6개 | `mng/app/Models/Documents/`, `mng/app/Models/DocumentTemplate*.php` | 존재 |
| DocumentTemplateController | `mng/app/Http/Controllers/DocumentTemplateController.php` | 존재 |
| DocumentController | `mng/app/Http/Controllers/DocumentController.php` | 존재 |
| 라우트 (templates, documents) | `mng/routes/web.php` 340-353줄 | 존재 |
| 양식 편집 Blade | `mng/resources/views/document-templates/edit.blade.php` (44.5KB) | 존재 |
| 문서 Blade (index/edit/show) | `mng/resources/views/documents/` | 존재 |

### 2.3 5130 레거시 검사 문서 현황

#### 수입검사 (instock)

| 항목 | 내용 |
|------|------|
| 위치 | `5130/instock/` |
| 자재별 검사 페이지 | 40+ PHP 파일 (`i_EGI155.php`, `i_SUSplate.php`, `i_wire.php`, `i_motor.php` 등) |
| 메인 로더 | `fetch_inspection.php` (21.8KB) - 자재코드별 동적 로딩 |
| 검사 필드 | 로트번호, 검사일, 납품업체, 품명, 규격, 단위, 품목코드, 입고량, 자재번호, 제조사 |
| 판정 방식 | 항목별 합격/불합격 -> 종합판정 자동계산 |
| LOT 관리 | `lotnum.txt` 파일 기반, YYMMDD-## 형식 |
| PDF 출력 | html2pdf.js 사용 |

#### 중간검사 (output)

| 검사 종류 | 파일 | DB 필드 |
|----------|------|---------|
| 절곡품 중간검사 | `viewMidInspectBending.php` (60.7KB) | `recordbendingMid` (JSON) |
| 스크린 중간검사 | `viewMidInspectScreen.php` (33.6KB) | `recordscreenMid` (JSON) |
| 슬랫 중간검사 | `viewMidInspectSlat.php` | `recordslatMid` (JSON) |
| 조인트바 검사 | `viewinspectionJointbar.php` (34.1KB) | `recordjointbar` (JSON) |

#### 검사 공통 구조
- 결재: 작성(판매/Order) -> 검토(생산) -> 승인(품질/QC)
- 검사 기준 이미지: `5130/img/inspection/` (20+ 이미지)
- 데이터: JSON으로 DB 저장 (approval chain + measurements)
- QC 관리자 권한 제어 (이세희, 함신옥, 이경호, 노완호)

### 2.4 SAM(react) 현재 검사 컴포넌트

| 컴포넌트 | 경로 | 용도 |
|---------|------|------|
| ImportInspectionDocument | `react/src/.../quality/qms/components/documents/` | 수입검사 성적서 |
| ScreenInspectionDocument | 동일 경로 | 스크린 중간검사 성적서 |
| SlatInspectionDocument | 동일 경로 | 슬랫 중간검사 성적서 |
| BendingInspectionDocument | 동일 경로 | 절곡품 중간검사 성적서 |
| JointbarInspectionDocument | 동일 경로 | 조인트바 중간검사 성적서 |
| ProductInspectionDocument | 동일 경로 | 제품검사 성적서 |
| WorkLogContent | `react/src/components/production/WorkerScreen/` | 작업일지 |
| InspectionReportModal | `react/src/components/production/WorkOrders/documents/` | 중간검사 모달 |
| DocumentViewer | `react/src/components/document-system/viewer/` | 범용 문서 뷰어 |

**공통 컴포넌트 (document-system):**
- `DocumentHeader.tsx` - 문서 헤더 (로고, 결재라인)
- `QualityApprovalTable.tsx` - 품질 결재표
- `InfoTable.tsx` - 정보 테이블
- `DocumentViewer.tsx` - 문서 뷰어 (zoom, drag, print, download)

---

## 3. 대상 범위

### 3.1 Phase 1: mng 양식 관리 기능 완성 (수입검사)

수입검사 양식 20여종을 mng에서 동적으로 관리할 수 있도록 기존 코드를 보강한다.

| # | 작업 항목 | 상태 | 완료 기준 | 비고 |
|---|----------|:----:|----------|------|
| 1.1 | 기존 document-templates 편집 UI 점검 및 보완 | ✅ | `mng.sam.kr/document-templates/{id}/edit`에서 결재라인/기본필드/섹션/항목/컬럼 모두 CRUD 가능. 저장 후 DB에 정상 반영 확인 | 5개 탭 전체 CRUD 완료 확인 |
| 1.2 | 5130 수입검사 데이터 분석 및 양식 구조 설계 | ✅ | 라우팅 구조 + 대표 자재 2종(EGI, SUS) 상세 분석 완료. 나머지 21종은 Phase 1.3에서 개별 분석 병행 | viewJS.php 라우팅 + 공통패턴 추출 |
| 1.3 | 수입검사 양식 시드 데이터 생성 | ✅ | EGI(ID:7), SUS(ID:8) 2종 생성 완료. 각각 결재2+기본필드10+섹션1+검사항목7~8+컬럼7. 나머지 자재는 개별 분석 후 시더에 추가 | `IncomingInspectionTemplateSeeder.php` |
| 1.4 | 양식 미리보기 기능 | ✅ | edit.blade.php에 모달 미리보기 구현 완료. 결재란+기본정보+검사이미지+검사테이블(complex 지원)+Footer(비고+판정) 모두 렌더링 | 기존 구현 확인 완료 |
| 1.5 | 양식 복제 기능 | ✅ | API `POST /{id}/duplicate` + 목록 복제 버튼. 이름 입력 prompt → 전체 관계(결재/필드/섹션/항목/컬럼) 복제. 비활성 상태로 생성 | API+UI 구현 완료 |

### 3.2 Phase 2: mng 문서 생성/관리 기능

양식을 기반으로 실제 검사 문서를 생성하고 데이터를 입력/결재하는 기능.

| # | 작업 항목 | 상태 | 완료 기준 | 비고 |
|---|----------|:----:|----------|------|
| 2.1 | 문서 생성 (양식 선택 -> 빈 문서 생성) | ✅ | 양식 선택 후 빈 문서(DRAFT)가 documents 테이블에 생성됨. 문서번호 자동 채번 | 카테고리별 prefix (IQC/PRD/SLS/PUR), 결재라인 초기화, 기본필드 뷰 수정 완료 |
| 2.2 | 문서 데이터 입력 UI | ✅ | 양식의 columns/sections 기반 동적 테이블 렌더링. complex/select/check/measurement/text 컬럼 타입 지원. EAV 저장 (section_id, column_id, row_index) | field_key 패턴: s{섹션}_r{행}_c{컬럼}_sub{인덱스} |
| 2.3 | 결재 워크플로우 (제출/승인/반려) | ✅ | DRAFT→PENDING→APPROVED/REJECTED 전체 동작. 단계별 승인, 반려 사유 필수, 재제출 시 결재라인 초기화 | submit/approve/reject API + 승인·반려 UI |
| 2.4 | 문서 목록/검색/필터 | ✅ | 상태별(DRAFT/PENDING/APPROVED), 양식별, 날짜별 필터 동작. 페이징 포함 | 날짜 범위 필터(date_from/date_to) + DRAFT 문서 삭제 기능 추가 |
| 2.5 | 문서 PDF 출력 | ⏭️ | **추후 고려** - react에 이미 html2pdf.js 구현됨 (6.2 결정사항 #1 참고) | |

### 3.3 Phase 3: 중간검사 양식 추가

| # | 작업 항목 | 상태 | 완료 기준 | 비고 |
|---|----------|:----:|----------|------|
| 3.1 | 중간검사 양식 구조 설계 | ✅ | 절곡/스크린/슬랫/조인트바 4종의 검사항목/기준/판정방식 문서화 완료 | 섹션 5.2에 상세 설계. 절곡품 최고 복잡도(★5), 조인트바 최저(★1) |
| 3.2 | 5130 중간검사 데이터 이관 설계 | ✅ | recordbendingMid 등 JSON→양식 매핑 테이블 완성 | 섹션 5.3에 상세 설계. 6단계 이관 프로세스, 변환 규칙, 주의사항 문서화 |
| 3.3 | 중간검사 양식 시드 데이터 | ✅ | 4종 양식 seeder 생성, `mng.sam.kr/document-templates`에서 확인 가능 | MidInspectionTemplateSeeder: 조인트바(ID:10), 슬랫(ID:11), 스크린(ID:12), 절곡품(ID:13) |
| 3.4 | 검사 기준 이미지 관리 | ✅ | `5130/img/inspection/` 이미지 → `mng/public/img/inspection/`로 이관. 양식에서 참조 가능 | 27개 이미지. URL: `/img/inspection/{filename}.jpg` |

### 3.4 Phase 4: API 연동 및 mng JSON 화면 구현

| # | 작업 항목 | 상태 | 완료 기준 | 비고 |
|---|----------|:----:|----------|------|
| 4.1 | API 엔드포인트 설계 (양식 조회, 문서 CRUD) | ✅ | DocumentTemplate 읽기 전용 API(모델6+서비스+컨트롤러+FormRequest+라우트+Swagger). Document 결재 워크플로우 4개 엔드포인트 활성화(submit/approve/reject/cancel) | api 저장소 |
| 4.2 | mng에서 JSON 기반 문서 화면 구현 | ✅ | show.blade.php에 섹션 테이블 읽기전용 렌더링 구현(5가지 컬럼 타입). 종합판정+비고 Footer. 기존 버그 3건 수정(field_key/field_type/section.title) | mng 저장소 |
| 4.3 | mng에서 문서 데이터 입력/저장 연동 | ⏳ | JSON 화면에서 검사값 입력→API 호출→DB 저장. 판정(합격/불합격) 결과 저장 확인 | 6.2 결정사항 #2 적용 |
| 4.4 | 프론트엔드 담당자 협의 후 react 전환 결정 | ⏳ | mng 완성 후 프론트 담당자와 미팅. react 기존 컴포넌트는 미수정 (6.2 결정사항 #4) | 협의 결과 문서화 |

### 3.5 Phase 5 (추후): 기타 문서 확장

| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 5.1 | 제품검사 양식 | ⏳ | Phase 3 이후 |
| 5.2 | 작업일지 양식 | ⏳ | WorkLogContent 기반 |
| 5.3 | 견적서/거래명세서/발주서 양식 | ⏳ | 기존 문서 모달 분석 필요 |

---

## 4. 아키텍처 설계

### 4.1 시스템 흐름

```
[mng - 양식 관리]                    [api - REST API]                [SAM - react 프론트]

DocumentTemplate CRUD  ---------->  GET /document-templates         양식 목록/상세
  - 결재라인 설정                    GET /document-templates/{id}
  - 기본필드 설정
  - 섹션/항목 설정                 POST /documents                  문서 생성
  - 컬럼 설정                      PUT  /documents/{id}             데이터 입력
                                    GET  /documents/{id}             문서 조회
Document 생성/관리  ------------>  POST /documents/{id}/submit      결재 제출
  - 데이터 입력                    POST /documents/{id}/approve     결재 승인
  - 결재 처리                      POST /documents/{id}/reject      결재 반려
  - PDF 출력                       GET  /documents/{id}/pdf         PDF 다운로드
```

### 4.2 JSON 응답 구조 (양식 상세)

```json
{
  "template": {
    "id": 1,
    "name": "EGI 1.55T 수입검사",
    "category": "incoming_inspection",
    "title": "수 입 검 사 성 적 서",
    "companyName": "케이디산업",
    "approvalLines": [
      { "name": "작성", "dept": "판매/Order", "role": "담당자", "sortOrder": 1 },
      { "name": "검토", "dept": "생산", "role": "담당자", "sortOrder": 2 },
      { "name": "승인", "dept": "품질", "role": "QC", "sortOrder": 3 }
    ],
    "basicFields": [
      { "label": "품명", "fieldType": "text", "sortOrder": 1 },
      { "label": "규격", "fieldType": "text", "sortOrder": 2 },
      { "label": "LOT NO", "fieldType": "text", "sortOrder": 3 },
      { "label": "검사일자", "fieldType": "date", "sortOrder": 4 },
      { "label": "납품업체", "fieldType": "text", "sortOrder": 5 },
      { "label": "검사자", "fieldType": "text", "sortOrder": 6 }
    ],
    "sections": [
      {
        "title": "가이드레일",
        "imagePath": "/storage/inspection/guiderail.jpg",
        "items": [
          {
            "category": "겉모양",
            "item": "사용상 결함이 될 흠이 없을 것",
            "standard": "KS D 3506",
            "method": "육안검사",
            "frequency": "체크검사",
            "regulation": "KS D 3506"
          },
          {
            "category": "치수",
            "item": "두께",
            "standard": "1.55 +/- 0.15",
            "method": "계측",
            "frequency": "입고시",
            "regulation": "KS D 3506"
          }
        ]
      }
    ],
    "columns": [
      { "label": "NO", "columnType": "text", "width": "50px", "sortOrder": 1 },
      { "label": "검사항목", "columnType": "text", "width": "120px", "sortOrder": 2 },
      { "label": "검사기준", "columnType": "text", "width": "150px", "sortOrder": 3 },
      {
        "label": "검사 DATA",
        "columnType": "complex",
        "groupName": "검사 DATA",
        "subLabels": ["1", "2", "3", "4", "5"],
        "width": "300px",
        "sortOrder": 4
      },
      { "label": "판정", "columnType": "select", "width": "80px", "sortOrder": 5 }
    ],
    "footerRemarkLabel": "부적합 내용",
    "footerJudgementLabel": "종합판정",
    "footerJudgementOptions": ["합격", "불합격"]
  }
}
```

### 4.3 JSON 응답 구조 (문서 상세)

```json
{
  "document": {
    "id": 1,
    "templateId": 1,
    "documentNo": "IQC-260131-01",
    "title": "EGI 1.55T 수입검사 성적서",
    "status": "APPROVED",
    "template": { "...위 구조와 동일..." },
    "basicData": {
      "품명": "전기 아연도금 강판",
      "규격": "EGI 1.55T",
      "LOT NO": "260131-01",
      "검사일자": "2026-01-31",
      "납품업체": "포스코",
      "검사자": "이세희"
    },
    "tableData": [
      {
        "sectionId": 1,
        "rows": [
          {
            "rowIndex": 0,
            "values": {
              "NO": "1",
              "검사항목": "겉모양",
              "검사기준": "사용상 결함 없을 것",
              "검사 DATA": { "1": "양호", "2": "양호", "3": "양호", "4": "-", "5": "-" },
              "판정": "적합"
            }
          }
        ]
      }
    ],
    "footerData": {
      "remark": "",
      "judgement": "합격"
    },
    "approvals": [
      { "step": 1, "role": "작성", "userName": "홍길동", "status": "APPROVED", "actedAt": "2026-01-31" },
      { "step": 2, "role": "검토", "userName": "김철수", "status": "APPROVED", "actedAt": "2026-01-31" },
      { "step": 3, "role": "승인", "userName": "이세희", "status": "APPROVED", "actedAt": "2026-01-31" }
    ]
  }
}
```

---

## 5. 5130 데이터 이관 계획

### 5.1 수입검사 자재 목록 (주요)

5130의 `instock/fetch_inspection.php`에서 자재코드별로 로딩하는 개별 페이지를 분석하여, 각 자재별 검사항목을 양식 시드 데이터로 변환한다.

| # | 자재 | 5130 파일 | 검사 항목 수 | 우선순위 |
|---|------|----------|:----------:|:-------:|
| 1 | EGI 1.55T (전기아연도금강판) | `i_EGI155.php` | ~8 | 높음 |
| 2 | SUS Plate (스테인리스강판) | `i_SUSplate.php` | ~6 | 높음 |
| 3 | GI Plate (아연도금강판) | `i_GIplate.php` | ~6 | 높음 |
| 4 | Wire (와이어) | `i_wire.php` | ~4 | 중간 |
| 5 | Motor (모터) | `i_motor.php` | ~5 | 중간 |
| 6 | Angle (앵글) | `i_angle.php` | ~4 | 중간 |
| 7-20+ | 기타 자재 | 개별 PHP 파일 | 다양 | 낮음 |

### 5.2 중간검사 양식 구조 설계 (Phase 3.1)

> **5130 레거시 분석 결과** - 4종 중간검사의 검사항목/기준/판정방식을 문서화

#### 5.2.0 공통 구조

**결재라인 (4종 공통)**

| step | name | dept | role |
|------|------|------|------|
| 1 | 작성 | 판매/Order | 담당자 |
| 2 | 검토 | 생산 | 담당자 |
| 3 | 승인 | 품질 | QC |

**기본필드 (4종 공통)**

| # | label | field_type | 비고 |
|---|-------|-----------|------|
| 1 | 품명 | text | 절곡품/스크린/철재스라트/조인트바 |
| 2 | 규격 | text | 제품 규격 |
| 3 | 로트크기 | text | 개소 수 |
| 4 | 발주처 | text | 고객사명 |
| 5 | 현장명 | text | 설치 현장 |
| 6 | 검사일자 | date | - |
| 7 | 검사자 | text | - |

**Footer (4종 공통)**
- `footer_remark_label`: "부적합 내용"
- `footer_judgement_label`: "종합판정"
- `footer_judgement_options`: ["합격", "불합격"]
- 종합판정 로직: 모든 행 "적" → 합격, 하나라도 "부" → 불합격

---

#### 5.2.1 절곡품 중간검사 (Bending Mid-Inspection)

**양식 정보**

| 항목 | 값 |
|------|-----|
| name | 절곡품 중간검사 성적서 |
| category | 품질/중간검사 |
| title | 절곡품 - 중간 검사 성적서 |
| 5130 DB필드 | `recordbendingMid` (JSON) |

**섹션 구조**: 제품 코드별 다른 검사 항목 (동적 구성)

구성품별 검사항목:

| 구성품 | 검사 항목 | 비고 |
|--------|----------|------|
| 가이드레일 (벽면형 120×70) | 겉모양(절곡상태), 길이, 너비, 간격(4포인트) | S1: 30/80/45/40mm |
| 가이드레일 (측면형 120×120) | 겉모양(절곡상태), 길이, 너비, 간격(6포인트) | S1: 30/70/45/35/95/90mm |
| 하단마감재 (60×40) | 겉모양, 너비(60mm) | 길이 3000/4000mm |
| 하단 L-BAR (17×60) | 겉모양, 너비(17mm) | - |
| 케이스/셔터박스 | 겉모양, 높이, 하단, 차이, 위치 | 양면/밑면/후면 |
| 연기차단재 (가이드레일용) | 너비(50mm), 간격(12mm) | - |
| 연기차단재 (케이스용) | 너비(80mm), 간격(12mm) | - |

**컬럼 구조**

| # | label | column_type | 비고 |
|---|-------|-----------|------|
| 1 | 분류/제품명 | text | 자동매핑 (KSS01 등) |
| 2 | 타입 | text | 벽면형/측면형/규격 |
| 3 | 겉모양(절곡상태) | check | 양호/불량 체크 |
| 4 | 길이 | complex | sub_labels: ['도면치수', '측정값'] |
| 5 | 너비 | complex | sub_labels: ['도면치수', '측정값'] |
| 6 | 간격 | complex | sub_labels: POINT별 ['도면치수', '측정값'] (가변) |
| 7 | 판정(적/부) | select | 자동계산 가능 |

**허용 공차**
- 길이: ±4mm
- 간격: ±2mm

**참조 이미지**: `bending_inspection1.jpg`, `bending_inspection2.jpg`, `guiderail_*`, `box_*`, `Lbar_mid`, `smoke`

**⚠️ 특이사항**: 절곡품은 제품 코드(KSS01/KSS02/KWE01)와 마감유형(S1/S2/S3)에 따라 검사 항목이 동적으로 변경됨. 현재 양식 시스템에서 이를 표현하려면 **가장 포괄적인 구성을 기본 양식으로 만들고**, 실제 문서 생성 시 해당 제품에 맞는 행만 활성화하는 방식 검토 필요.

---

#### 5.2.2 스크린 중간검사 (Screen Mid-Inspection)

**양식 정보**

| 항목 | 값 |
|------|-----|
| name | 스크린 중간검사 성적서 |
| category | 품질/중간검사 |
| title | 스크린 - 중간 검사 성적서 |
| 5130 DB필드 | `recordscreenMid` (JSON) |

**섹션: 스크린 검사 항목**

| # | 검사항목 | 타입 | 기준 | 비고 |
|---|---------|------|------|------|
| 겉모양-1 | 가공상태 | check | 양호/불량 | - |
| 겉모양-2 | 재봉상태 | check | 양호/불량 | - |
| 겉모양-3 | 조립상태 | check | 양호/불량 | - |
| 치수-① | 길이 | measurement | 도면치수 ±4mm | col10_SW/col10 |
| 치수-② | 높이 | measurement | 도면치수 ±40mm | col11_SH/col11 |
| 치수-③ | 간격 | check | 400 이하 → OK/NG | 고정 기준 |

**컬럼 구조**

| # | label | column_type | 비고 |
|---|-------|-----------|------|
| 1 | 일련번호 | text | 자동 (제품 순번) |
| 2 | 가공상태 | check | 양호/불량 |
| 3 | 재봉상태 | check | 양호/불량 |
| 4 | 조립상태 | check | 양호/불량 |
| 5 | ①길이 | complex | sub_labels: ['도면치수', '측정값'] |
| 6 | ②높이 | complex | sub_labels: ['도면치수', '측정값'] |
| 7 | ③간격 | complex | sub_labels: ['기준치', 'OK/NG'] |
| 8 | 판정(적/부) | select | 자동계산 |

**행 개수**: 발주 제품 수(estimateList)만큼 동적 생성

---

#### 5.2.3 슬랫(철재스라트) 중간검사 (Slat Mid-Inspection)

**양식 정보**

| 항목 | 값 |
|------|-----|
| name | 슬랫 중간검사 성적서 |
| category | 품질/중간검사 |
| title | 슬랫 - 중간 검사 성적서 |
| 5130 DB필드 | `recordslatMid` (JSON) |

**섹션: 슬랫 검사 항목**

| # | 검사항목 | 타입 | 기준 | 비고 |
|---|---------|------|------|------|
| 겉모양-1 | 가공상태 | check | 양호/불량 | - |
| 겉모양-2 | 조립상태 | check | 양호/불량 | 재봉상태 없음 (스크린과 차이) |
| 치수-① | 높이(1) | measurement | 16.5 ± 1mm | 고정 기준값 |
| 치수-② | 높이(2) | measurement | 14.5 ± 1mm | 고정 기준값 |
| 치수-③ | 길이(엔드락제외) | measurement | 도면치수 ±4mm | col10 |

**컬럼 구조**

| # | label | column_type | 비고 |
|---|-------|-----------|------|
| 1 | 일련번호 | text | 자동 |
| 2 | 가공상태 | check | 양호/불량 |
| 3 | 조립상태 | check | 양호/불량 |
| 4 | ①높이 | complex | sub_labels: ['기준(16.5±1)', '측정값'] |
| 5 | ②높이 | complex | sub_labels: ['기준(14.5±1)', '측정값'] |
| 6 | ③길이 | complex | sub_labels: ['도면치수', '측정값'] |
| 7 | 판정(적/부) | select | 자동계산 |

**행 개수**: 발주 제품 수(estimateSlatList)만큼 동적 생성

**스크린 vs 슬랫 차이점**

| 항목 | 스크린 | 슬랫 |
|------|--------|------|
| 겉모양 | 3개 (가공/재봉/조립) | 2개 (가공/조립) |
| 치수①② | 길이·높이 (도면치수) | 높이(1)(2) (고정값 16.5/14.5) |
| 치수③ | 간격 (400이하, OK/NG) | 길이 (도면치수 ±4mm) |
| 공차 | ±4mm, ±40mm | ±1mm, ±1mm, ±4mm |

---

#### 5.2.4 조인트바 중간검사 (Jointbar Mid-Inspection)

**양식 정보**

| 항목 | 값 |
|------|-----|
| name | 조인트바 중간검사 성적서 |
| category | 품질/중간검사 |
| title | 조인트바 - 중간 검사 성적서 |
| 5130 DB필드 | `recordjointbar` (JSON) |

**섹션: 조인트바 검사 항목**

| # | 검사항목 | 타입 | 기준값 | 공차 |
|---|---------|------|-------|------|
| 겉모양-1 | 가공상태 | check | 양호/불량 | - |
| 겉모양-2 | 조립상태 | check | 양호/불량 | - |
| 치수-① | 높이(1) | measurement | 16.5mm | ±1mm |
| 치수-② | 높이(2) | measurement | 14.5mm | ±1mm |
| 치수-③ | 길이(엔드락제외) | measurement | 300mm | ±4mm |
| 치수-④ | 간격 | measurement | 150mm | ±4mm |

**컬럼 구조**

| # | label | column_type | 비고 |
|---|-------|-----------|------|
| 1 | 일련번호 | text | 자동 |
| 2 | 가공상태 | check | 양호/불량 |
| 3 | 조립상태 | check | 양호/불량 |
| 4 | ①높이 | complex | sub_labels: ['기준(16.5±1)', '측정값'] |
| 5 | ②높이 | complex | sub_labels: ['기준(14.5±1)', '측정값'] |
| 6 | ③길이 | complex | sub_labels: ['기준(300±4)', '측정값'] |
| 7 | ④간격 | complex | sub_labels: ['기준(150±4)', '측정값'] |
| 8 | 판정(적/부) | select | 자동계산 |

**행 개수**: 단일 행 (제품 1건 단위 검사)

**참조 이미지**: `jointbar_inspection.jpg`

---

#### 5.2.5 4종 비교 요약

| 항목 | 절곡품 | 스크린 | 슬랫 | 조인트바 |
|------|--------|--------|------|---------|
| 겉모양 수 | 1 (절곡상태) | 3 (가공/재봉/조립) | 2 (가공/조립) | 2 (가공/조립) |
| 치수 항목 | 길이+너비+간격(가변) | 3 (길이/높이/간격) | 3 (높이×2/길이) | 4 (높이×2/길이/간격) |
| 행 구성 | 구성품별 (동적) | 발주제품별 (동적) | 발주제품별 (동적) | 단일 행 |
| 기준값 | 도면치수+포인트별 | 도면치수+고정(400) | 고정(16.5/14.5)+도면 | 전체 고정값 |
| 공차 | ±4mm/±2mm | ±4/±40mm | ±1/±1/±4mm | ±1/±1/±4/±4mm |
| 참조이미지 | 다수 (구성품별) | 별도 | 별도 | 1장 |
| 복잡도 | ★★★★★ (최고) | ★★★ | ★★☆ | ★☆ (최저) |

#### 5.2.6 양식 시스템 매핑 전략

**현재 양식 시스템의 한계와 대응**:

1. **조인트바/슬랫**: 현재 양식 구조(섹션+항목+컬럼)로 **그대로 표현 가능**. 수입검사와 동일 패턴으로 시더 생성.

2. **스크린**: 겉모양 check 컬럼 + complex 측정 컬럼 조합으로 표현 가능. 행이 발주 제품별 동적이므로 **문서 생성 시 행 수를 결정**하는 로직 필요.

3. **절곡품**: 제품 코드별로 검사 항목이 완전히 달라지므로 **가장 복잡**. 접근 방식:
   - **Option A**: 포괄 양식 1개 + 문서 생성 시 해당 행만 활성화
   - **Option B**: 제품 유형별 양식 분리 (S1/S2/S3 별도)
   - **Option C (권장)**: 기본 양식에 구성품 목록만 정의하고, **문서 생성 시 제품 코드에 따라 동적으로 행 구성** (Phase 3.3에서 구현)

4. **check 컬럼 타입**: 현재 시스템에 `check` 컬럼 타입이 이미 존재. 양호/불량 체크박스로 사용 가능.

### 5.3 중간검사 데이터 이관 설계 (Phase 3.2)

> **5130 JSON 구조 → 새 양식 시스템(EAV) 매핑**

#### 5.3.1 5130 JSON 공통 배열 구조

4종 모두 동일한 배열 인덱스 패턴:

```
recordXxxMid = [
  [0]: { approval: { writer: {name,date}, reviewer: {name,date}, approver: {name,date} } }
  [1]: { inputValue: { ... } }       ← 절곡: named object / 스크린·슬랫·조인트바: flat array
  [2]: { num: "주문번호" }
  [3]: { tablename: "output" }
  [4]: { update_log: "..." }          ← 슬랫·조인트바는 없음
  [5]: { checkboxData: [ {good:[], bad:[], judgement:""}, ... ] }  ← 슬랫·조인트바는 [4]
]
```

#### 5.3.2 JSON → EAV 매핑 테이블

**결재 데이터 (JSON[0] → document_approvals)**

| JSON 경로 | EAV 대상 | 비고 |
|-----------|---------|------|
| `[0].approval.writer.name` | `document_approvals` (step=1, user→name) | 작성자 |
| `[0].approval.writer.date` | `document_approvals` (step=1, acted_at) | mm/dd → datetime |
| `[0].approval.reviewer.name` | `document_approvals` (step=2, user→name) | 검토자 |
| `[0].approval.reviewer.date` | `document_approvals` (step=2, acted_at) | mm/dd → datetime |
| `[0].approval.approver.name` | `document_approvals` (step=3, user→name) | 승인자 |
| `[0].approval.approver.date` | `document_approvals` (step=3, acted_at) | mm/dd → datetime |

**기본필드 (JSON[1].inputValue → document_data, section_id=null)**

| JSON 경로 | field_key | 비고 |
|-----------|----------|------|
| `[1].inputValue.inspectdate` | `basic_inspectdate` | 검사일자 |
| `[1].inputValue.reviewer_sub` | `basic_reviewer` | 검사자 |
| `[1].inputValue.*_false_comment` | `footer_remark` | 부적합 내용 |
| `[1].inputValue.resultJudgement` | `footer_judgement` | 종합판정 |

**절곡품 측정 데이터 (JSON[1].inputValue → document_data)**

| JSON 경로 | field_key 패턴 | 비고 |
|-----------|---------------|------|
| `[1].inputValue.lengthMeasurement[i]` | `s{섹션}_r{i}_length` | 길이 측정값 |
| `[1].inputValue.widthMeasurement[i]` | `s{섹션}_r{i}_width` | 너비 측정값 |
| `[1].inputValue.gapMeasurement[i]` | `s{섹션}_r{i}_gap_{point}` | 간격 측정값 (포인트별) |

**스크린/슬랫/조인트바 측정 데이터 (JSON[1].inputValue → document_data)**

| JSON 경로 | field_key 패턴 | 비고 |
|-----------|---------------|------|
| `[1].inputValue[n]` (col{row}_input_{dim}) | `s{섹션}_r{row}_c{col}_sub{dim}` | 순차 인덱스 → 행·컬럼 매핑 |

**체크박스 데이터 (JSON[5/4].checkboxData → document_data)**

| JSON 경로 | field_key 패턴 | 비고 |
|-----------|---------------|------|
| `checkboxData[row].good[col]` | `s{섹션}_r{row}_c{checkCol}_good` | 양호 체크 |
| `checkboxData[row].bad[col]` | `s{섹션}_r{row}_c{checkCol}_bad` | 불량 체크 |
| `checkboxData[row].judgement` | `s{섹션}_r{row}_judgement` | 행별 판정 (적/부) |

#### 5.3.3 이관 시 데이터 변환 규칙

| 변환 항목 | 5130 형식 | 새 시스템 형식 | 변환 로직 |
|----------|----------|-------------|----------|
| 날짜 (결재) | `"1/31"` (mm/dd) | `datetime` | 연도 추정 필요 (output.indate 기준) |
| 날짜 (검사) | `"2026-01-31"` | `date` | 그대로 사용 |
| 체크박스 | `true/false` | `"1"/"0"` | boolean → string |
| 판정 | `"적"/"부"` | `"적"/"부"` | 그대로 사용 |
| 종합판정 | `"합격"/"불합격"` | `"합격"/"불합격"` | 그대로 사용 |
| 측정값 | `number/string` | `string` | EAV field_value는 string |
| 결재자 이름 | `string` | `user_id (FK)` | 이름→사용자 테이블 매칭 필요 |

#### 5.3.4 이관 프로세스 설계

```
Step 1: output 테이블에서 recordXxxMid IS NOT NULL 레코드 추출
    ↓
Step 2: 각 레코드에 대해 해당 양식 템플릿 매핑
    - recordbendingMid → 절곡품 중간검사 양식 (template_id)
    - recordscreenMid → 스크린 중간검사 양식
    - recordslatMid → 슬랫 중간검사 양식
    - recordjointbar → 조인트바 중간검사 양식
    ↓
Step 3: documents 테이블에 문서 생성
    - template_id, tenant_id, document_no (MID-YYMMDD-NN)
    - title: "{양식명} - {현장명}"
    - status: APPROVED (이미 완료된 검사)
    - created_at: output.indate 기준
    ↓
Step 4: document_approvals 생성
    - JSON[0].approval → 3개 결재 레코드
    - 이름→user_id 매칭 (매칭 실패 시 created_by = system)
    - status: APPROVED, acted_at: 변환된 날짜
    ↓
Step 5: document_data (EAV) 생성
    - 기본필드: inspectdate, reviewer → field_key 매핑
    - 체크박스: checkboxData → good/bad/judgement 매핑
    - 측정값: inputValue → 행·컬럼 인덱스 매핑
    - Footer: false_comment → footer_remark, resultJudgement → footer_judgement
    ↓
Step 6: 검증
    - 원본 JSON과 변환 결과 대조
    - 종합판정·행별 판정 일치 확인
```

#### 5.3.5 이관 대상 규모 추정

| 검사 종류 | DB 필드 | 조건 | 비고 |
|----------|---------|------|------|
| 절곡품 | recordbendingMid | IS NOT NULL AND != '' AND != '{}' | output 테이블 |
| 스크린 | recordscreenMid | 동일 | output 테이블 |
| 슬랫 | recordslatMid | 동일 | output 테이블 |
| 조인트바 | recordjointbar | 동일 | output 테이블 |

> ⚠️ 실제 레코드 수는 5130 DB 조회 필요 (Phase 3.2 완료 기준 설계만 완성, 실행은 Phase 4 이후)

#### 5.3.6 이관 시 주의사항

1. **절곡품 inputValue 구조 차이**: 절곡품만 named object (`lengthMeasurement[]`, `widthMeasurement[]`, `gapMeasurement[]`), 나머지 3종은 flat array. 이관 스크립트에서 분기 처리 필요.

2. **update_log 유무**: 스크린만 별도 `update_log` 컬럼 업데이트. 슬랫·조인트바는 JSON 내부에만 포함 (실제로는 비어있을 수 있음).

3. **결재자 이름 매칭**: 5130의 결재자는 문자열 이름만 저장. 새 시스템의 user_id(FK)로 변환 시 users 테이블에서 name 매칭 필요. 동명이인 주의.

4. **행 수 불일치 가능성**: 5130에서 발주 제품 수에 따라 행이 동적 생성됨. 이관 시 원본 행 수 보존 필요.

5. **이미지 참조**: 5130 JSON에는 이미지 참조명(`guiderail_wall_mid` 등)이 포함됨. 이관 시 새 시스템의 이미지 경로로 변환 필요.

### 5.4 검사 기준 이미지 이관 (Phase 3.4 완료)

`5130/img/inspection/` → `mng/public/img/inspection/` (27개 파일)

| 분류 | 파일명 | 용도 |
|------|--------|------|
| 절곡-기준서 | `bending_inspection1.jpg`, `bending_inspection2.jpg` | 가이드레일/케이스/하단 기준 |
| 가이드레일-벽면 | `guiderail_wall_mid.jpg`, `_KSS02.jpg`, `_add.jpg`, `_slat.jpg`, `_add_slat.jpg`, `_slatKQTS01.jpg` | S1/S2/S3/슬랫변형 |
| 가이드레일-측면 | `guiderail_side_mid.jpg`, `_KSS02.jpg`, `_add.jpg`, `_slat.jpg`, `_add_slat.jpg`, `_slatKQTS01.jpg` | S1/S2/S3/슬랫변형 |
| 하단마감재 | `bottombar_KSS01KWE01.jpg`, `_add.jpg`, `_KTE01KQTS01.jpg`, `_add.jpg` | 표준/특수마감 |
| 케이스 | `box_both.jpg`, `box_both500x380.jpg`, `box_bottom.jpg`, `box_rear.jpg` | 양면/밑면/후면 |
| 기타 | `Lbar_mid.jpg`, `smoke.jpg` | L-BAR, 연기차단재 |
| 스크린 | `screen_inspection.jpg` | 스크린 기준서 |
| 슬랫 | `slat_inspection.jpg` | 슬랫 기준서 |
| 조인트바 | `jointbar_inspection.jpg` | 조인트바 기준서 |

**접근 URL**: `https://mng.sam.kr/img/inspection/{filename}.jpg`

---

## 6. 기술 결정사항

### 6.1 확정된 사항

| 항목 | 결정 | 이유 |
|------|------|------|
| 양식 관리 위치 | mng (Laravel + Blade) | 관리자 전용, HTMX 기반 UI 이미 존재 |
| 데이터 저장 패턴 | EAV (document_data 테이블) | 이미 설계됨, 동적 필드 지원 |
| 문서 상태 | DRAFT -> PENDING -> APPROVED/REJECTED/CANCELLED | 이미 구현됨 |
| API 제공 | api 저장소 (Laravel REST API) | SAM 표준 아키텍처 |
| 프론트엔드 소비 | react (Next.js) JSON 렌더링 | 기존 document-system 컴포넌트 확장 |

### 6.2 검토 완료 사항 (2026-01-31 확정)

| # | 항목 | 결정 | 근거 |
|---|------|------|------|
| 1 | PDF 생성 | **추후 고려** | react에 이미 구현됨 (html2pdf.js + DocumentViewer). mng 단계에서는 PDF 불필요 |
| 2 | 검사 판정 로직 | **프론트에서 입력, 결과만 저장** | 양식이 검사항목/기준을 정의하고, 프론트에서 사용자가 입력. 저장 시 입력값+판정 결과를 그대로 저장. 별도 판정 엔진 불필요 |
| 3 | 양식 버전 관리 | **수정 시 새 버전 생성** | 요청마다 검사 기준이 다를 수 있으므로 버전 관리 필수. document_templates에 version 컬럼 추가 필요 |
| 4 | 기존 react 컴포넌트 전환 | **기존 react 미수정** | mng에서 JSON 기반 화면 구현까지만 개발. 이후 프론트엔드 담당자와 협의하여 react 전환 여부 결정 |

---

## 7. 컨펌 대기 목록

| # | 항목 | 변경 내용 | 영향 범위 | 상태 |
|---|------|----------|----------|------|
| 1 | API 엔드포인트 추가 | `/api/v1/document-templates` (2), `/api/v1/documents` (5+4결재) | api 저장소 | ✅ Phase 4.1 완료 |
| 2 | DB 마이그레이션 변경 여부 | 기존 테이블로 충분한지 vs version 컬럼 추가 필요 (6.2 #3 확정) | api 저장소 | ⏳ Phase 1 중 |
| 3 | ~~검사 판정 로직 위치~~ | ~~프론트 vs 백엔드~~ → **프론트 입력, 결과만 저장** | - | ✅ 해결됨 (6.2 #2) |
| 4 | ~~PDF 생성 방식~~ | ~~클라이언트 vs 서버~~ → **추후 고려** (react 기 구현) | - | ✅ 해결됨 (6.2 #1) |

---

## 8. 변경 이력

> 📎 별도 파일로 관리: [`document-management-system-changelog.md`](./document-management-system-changelog.md)

---

## 9. 참고 문서 및 파일

### 프로젝트 문서
- `docs/specs/database-schema.md` - DB 스키마
- `docs/standards/quality-checklist.md` - 품질 체크리스트
- `mng/CLAUDE.md` - MNG 프로젝트 규칙

### 기존 코드 (mng)
- `mng/app/Models/DocumentTemplate.php` - 양식 모델
- `mng/app/Models/Documents/Document.php` - 문서 모델
- `mng/app/Http/Controllers/DocumentTemplateController.php` - 양식 컨트롤러
- `mng/app/Http/Controllers/DocumentController.php` - 문서 컨트롤러
- `mng/resources/views/document-templates/edit.blade.php` - 양식 편집 UI (44.5KB)
- `mng/routes/web.php` 340-353줄 - 라우트

### 기존 코드 (react)
- `react/src/components/document-system/` - 문서 공통 시스템
- `react/src/app/[locale]/(protected)/quality/qms/components/documents/` - QMS 검사 문서
- `react/src/components/production/WorkerScreen/WorkLogContent.tsx` - 작업일지
- `react/src/components/production/WorkOrders/documents/` - 중간검사

### 5130 레거시
- `5130/instock/fetch_inspection.php` - 수입검사 메인 로더 (21.8KB)
- `5130/instock/i_*.php` - 자재별 수입검사 페이지 (40+)
- `5130/output/viewMidInspect*.php` - 중간검사 성적서
- `5130/output/viewinspectionJointbar.php` - 조인트바 검사
- `5130/img/inspection/` - 검사 기준 이미지 (20+)

### DB 마이그레이션
- `api/database/migrations/2026_01_26_200000_create_document_templates_table.php`
- `api/database/migrations/2026_01_28_200000_create_documents_table.php`

---

## 11. Phase별 상세 실행 절차

> 각 Phase 작업 시 이 섹션을 먼저 읽고 진행한다.

### 11.1 Phase 1.1 - 기존 document-templates 편집 UI 점검 및 보완

**목표**: `mng.sam.kr/document-templates/{id}/edit`에서 수입검사 양식에 필요한 모든 구성요소를 관리할 수 있는지 확인하고 부족한 부분을 보완한다.

**사전 조건**: 없음 (첫 번째 작업)

**실행 절차**:

```
Step 1: 현재 UI 분석
├── mng/resources/views/document-templates/edit.blade.php (44.5KB) 읽기
├── 기존 기능 목록 정리:
│   - 양식 기본정보 (이름, 카테고리, 제목, 회사명) 편집 가능?
│   - 결재라인 (approval_lines) CRUD 가능?
│   - 기본필드 (basic_fields) CRUD 가능?
│   - 섹션 (sections) CRUD 가능?
│   - 섹션 항목 (section_items) CRUD 가능?
│   - 컬럼 (columns) CRUD 가능?
│   - footer_remark_label, footer_judgement_label, footer_judgement_options 편집 가능?
└── 누락된 기능 목록화

Step 2: 브라우저에서 실제 동작 확인
├── https://mng.sam.kr/document-templates 접속
├── 기존 양식 편집 시도 (or 새 양식 생성 후 편집)
├── 각 탭/섹션별 CRUD 동작 확인
└── JS 에러, 저장 실패 등 이슈 기록

Step 3: 보완 작업
├── 누락된 CRUD 기능 구현 (Blade + HTMX + Alpine.js)
├── DocumentTemplateController 메서드 보강
├── 유효성 검증 추가 (FormRequest 패턴)
└── 섹션 항목(section_items)의 drag-drop 정렬 (있는 경우 확인, 없으면 sort_order 수동 관리)

Step 4: 검증
├── 새 양식 생성 → 모든 하위 요소 추가 → 저장 → DB 확인
├── 기존 양식 수정 → 저장 → 정상 반영 확인
└── 양식 삭제 → 하위 요소 cascade 삭제 확인
```

### 11.2 Phase 1.2 - 5130 수입검사 데이터 분석

**목표**: 5130의 자재별 수입검사 파일을 분석하여, 양식 시드 데이터로 변환할 수 있는 구조화된 데이터를 생성한다.

**상태**: ✅ 완료 (2026-01-31, 경량 분석)

**분석 결과**:

#### 라우팅 구조

`5130/instock/common/viewJS.php`의 `viewBoardInstock()` 함수가 **item_name(품명) 기준 switch-case**로 개별 검사 페이지(`i_*.php`)를 팝업 호출한다.

- `fetch_inspection.php` = 데이터 입력 폼 (목록에서 호출)
- `i_*.php` = 검사 성적서 뷰 (viewinspection 버튼에서 호출)
- 총 23개 파일, 품명별 1:1 또는 N:1 매핑

#### 자재 → 검사파일 매핑 (23개)

| 품명 | 파일 | 비고 |
|---|---|---|
| EGI1.55T, EGI1.15T, EGI1.6T | `i_EGI155.php` | 전기아연도금강판 |
| SUS1.55T, SUS1.5T, SUS1.2T | `i_SUSplate.php` | 스테인리스강판 |
| GI0.5T, GI0.45T | `i_GIplate.php` | 아연도금강판 |
| 앵글 | `i_angle.php` | |
| 받침용앵글 | `i_anglebottom.php` | |
| 방화유리 | `i_antifireglass.php` | |
| 절곡코일(EGI) | `i_bendingcoil.php` | spec 앞3자=EGI |
| 베어링부 | `i_bracket.php` | |
| 바이오세라크울96K | `i_cerakwool.php` | |
| 연동제어기 | `i_controller.php` | |
| 화이바원단 | `i_fiber.php` | |
| 내화충진재 | `i_Fireproof_sealings.php` | |
| 내화실 | `i_fireproofWire.php` | |
| 전동개폐기 | `i_motor.php` | |
| 평철 | `i_platesteel.php` | |
| 마환봉 | `i_pole.php` | |
| 각파이프 | `i_recpipe.php` | |
| 감기샤프트 | `i_shaft.php` | |
| 실리카원단 | `i_sillica.php` | |
| 슬랫코일 | `i_slatcoil.php` | |
| 절곡코일(SUS) | `i_SUScoil.php` | spec 앞3자=SUS |
| 와이어원단 | `i_wire.php` | 기본 |
| 와이어원단(대한) | `i_wireDaehan.php` | remarks에 '대한' 포함 시 |

#### 대표 자재 분석: EGI 1.55T (`i_EGI155.php`)

| NO | 검사항목 | 검사기준 | 검사방식 | 검사주기 | 데이터 타입 |
|---|---|---|---|---|---|
| 1 | 겉모양 | 사용상 해로울 결함이 없을 것 | 육안검사 | n=3, c=0 | OK/NG 체크 ×3 |
| 2 | 치수-두께 | 두께별 허용범위 (±0.07~±0.12, 4구간) | 체크검사 | n=3, c=0 | 측정값 ×3 |
| 2 | 치수-너비 | 1250 미만: +7/-0 | 체크검사 | n=3, c=0 | 측정값 ×3 |
| 2 | 치수-길이 | 길이별 허용범위 (+10~+20/-0, 3구간) | 체크검사 | n=3, c=0 | 측정값 ×3 |
| 3 | 인장강도 (N/mm²) | 270 이상 | 밀시트 | 입고시 | 단일값 |
| 4 | 연신율 (%) | 두께별 36~38 이상 (3구간) | 밀시트 | 입고시 | 단일값 |
| 5 | 아연 최소 부착량 (g/m²) | 한면 17 이상 | 밀시트 | 입고시 | 단일값 |

#### 대표 자재 분석: SUS Plate (`i_SUSplate.php`)

| NO | 검사항목 | 검사기준 | 검사방식 | 검사주기 | 데이터 타입 |
|---|---|---|---|---|---|
| 1 | 겉모양 | 사용상 해로울 결함이 없을 것 | 육안검사 | n=3, c=0 | OK/NG 체크 ×3 |
| 2 | 치수-두께 | 두께별 허용범위 (±0.10~±0.12, 2구간) | 체크검사 | n=3, c=0 | 측정값 ×3 |
| 2 | 치수-너비 | 1250 미만: +7/-0 | 체크검사 | n=3, c=0 | 측정값 ×3 |
| 2 | 치수-길이 | 길이별 허용범위 (+10~+20/-0, 2구간) | 체크검사 | n=3, c=0 | 측정값 ×3 |
| 3 | 항복강도 (N/mm²) | 205 이상 | 밀시트 | 입고시 | 단일값 |
| 4 | 인장강도 (N/mm²) | 520 이상 | 밀시트 | 입고시 | 단일값 |
| 5 | 연신율 (%) | 40 이상 | 밀시트 | 입고시 | 단일값 |
| 6 | 경도 (HV) | 200 이하 | 밀시트 | 입고시 | 단일값 |

#### 공통 패턴 요약

**공통 구조 (모든 자재 동일):**
- **결재**: 담당 / 부서장 (2단계)
- **기본정보**: 품명, 규격(두께×너비×길이), 납품업체/제조업체, 로트번호, 자재번호, 검사일자, 로트크기, 검사자
- **검사 테이블 컬럼**: NO / 검사항목 / 검사기준 / 검사방식 / 검사주기 / 측정치(n1,n2,n3) / 판정(적/부)
- **Footer**: 부적합 내용 + 종합판정(합격/불합격)
- **판정 로직**: JS 자동 계산 (모든 항목 적→합격, 하나라도 부→불합격)
- **저장**: JSON(`iList` hidden field) → AJAX POST → `insert_iList.php`

**자재별 차이점:**
- 검사항목 수/종류 (EGI: 5항목 7행, SUS: 6항목 8행)
- 기준값 범위 (두께별 허용 오차, 강도/경도 기준 등)
- 두께 범위 구간 수 (EGI: 4구간, SUS: 2구간)
- 밀시트 항목 차이 (EGI: 인장+연신+아연, SUS: 항복+인장+연신+경도)

> **결론**: 나머지 21개 자재는 Phase 1.3 시드 데이터 생성 시 개별 분석하면서 병행 진행

### 11.3 Phase 1.3 - 수입검사 양식 시드 데이터 생성

**실행 절차**:

```
Step 1: Seeder 파일 생성
├── mng/database/seeders/IncomingInspectionTemplateSeeder.php 생성
├── 1.2에서 정리한 데이터 기반
└── 주요 자재 10종 양식 생성 (EGI, SUS, GI, Wire, Motor, Angle 등)

Step 2: 실행 및 검증
├── php artisan db:seed --class=IncomingInspectionTemplateSeeder
├── mng.sam.kr/document-templates 에서 목록 확인
└── 각 양식 편집 화면에서 데이터 정합성 확인
```

---

## 12. 자기완결성 점검 결과

### 12.1 체크리스트 검증

| # | 검증 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 1 | 작업 목적이 명확한가? | ✅ | 섹션 1.1 배경 |
| 2 | 성공 기준이 정의되어 있는가? | ✅ | 각 Phase 작업 항목에 "완료 기준" 컬럼 추가됨 |
| 3 | 작업 범위가 구체적인가? | ✅ | 섹션 3 Phase 1-5 + 섹션 11 상세 절차 |
| 4 | 의존성이 명시되어 있는가? | ✅ | 기존 DB/모델/컨트롤러 현황 + 새 세션 가이드 |
| 5 | 참고 파일 경로가 정확한가? | ✅ | 절대 경로 + 상대 경로 모두 명시 |
| 6 | 단계별 절차가 실행 가능한가? | ✅ | 섹션 11 Phase별 Step-by-step 절차 |
| 7 | 검증 방법이 명시되어 있는가? | ✅ | 각 Phase 완료 기준에 검증 방법 포함 |
| 8 | 모호한 표현이 없는가? | ✅ | 구체적 파일/테이블/컬럼/URL 명시 |

### 12.2 새 세션 시뮬레이션 테스트

| 질문 | 답변 가능 | 참조 섹션 |
|------|:--------:|----------|
| Q1. 이 작업의 목적은 무엇인가? | ✅ | 1.1 배경 |
| Q2. 어디서부터 시작해야 하는가? | ✅ | 🚀 새 세션 시작 가이드 + 📍 현재 진행 상태 |
| Q3. 어떤 파일을 수정해야 하는가? | ✅ | 새 세션 가이드 "핵심 파일" + 2.2 + 9. 참고 파일 |
| Q4. 작업 완료 확인 방법은? | ✅ | 각 Phase "완료 기준" 컬럼 |
| Q5. 막혔을 때 참고 문서는? | ✅ | 9. 참고 문서 + 새 세션 가이드 |
| Q6. mng 기술 스택과 로컬 환경은? | ✅ | 새 세션 가이드 "프로젝트 정보" |
| Q7. 모델 관계와 DB 구조는? | ✅ | 새 세션 가이드 "모델 관계 구조" + 2.1 |
| Q8. Phase 1.1의 구체적 첫 단계는? | ✅ | 11.1 상세 실행 절차 |

**결과**: 8/8 통과 - 자기완결성 확보

### 12.3 보완 이력

| 날짜 | 항목 | 원본 | 보완 내용 |
|------|------|------|----------|
| 2026-01-31 | 초기 검증 | - | 5/5 통과 |
| 2026-01-31 | 자기완결성 강화 | 새 세션에서 시작 불가 | 🚀 새 세션 시작 가이드 추가, 절대 경로/기술 스택/모델 코드 인라인, Phase 완료 기준 추가, 섹션 11 상세 실행 절차 추가, 컨펌 대기 목록 해결 항목 반영 |

---

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