1001 lines
40 KiB
Markdown
1001 lines
40 KiB
Markdown
|
|
# 중간검사 성적서 시스템 구현 계획
|
||
|
|
|
||
|
|
> **작성일**: 2026-02-07
|
||
|
|
> **목적**: 작업자 화면에서 개소별 중간검사 데이터를 저장하고, 검사성적서보기 시 문서 템플릿 기반 성적서로 합쳐서 표시하는 시스템 구축
|
||
|
|
> **기준 문서**: `docs/plans/document-management-system-plan.md`, `docs/specs/database-schema.md`
|
||
|
|
> **상태**: 📋 계획 수립 완료 → 사용자 검토 대기
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🚀 새 세션 시작 가이드
|
||
|
|
|
||
|
|
> **이 섹션은 새 세션에서 이 문서만 보고 작업을 시작할 수 있도록 작성되었습니다.**
|
||
|
|
|
||
|
|
### 프로젝트 정보
|
||
|
|
|
||
|
|
| 항목 | 내용 |
|
||
|
|
|------|------|
|
||
|
|
| **작업 프로젝트** | `react` (프론트엔드) + `api` (백엔드) |
|
||
|
|
| **react 절대 경로** | `/Users/kent/Works/@KD_SAM/SAM/react/` |
|
||
|
|
| **api 절대 경로** | `/Users/kent/Works/@KD_SAM/SAM/api/` |
|
||
|
|
| **mng 절대 경로** | `/Users/kent/Works/@KD_SAM/SAM/mng/` (양식 관리 참조) |
|
||
|
|
| **기술 스택** | Next.js 15 (react) / Laravel 12 (api) |
|
||
|
|
| **로컬 URL** | `https://dev.sam.kr/production/worker-screen` |
|
||
|
|
| **관련 계획서** | `docs/plans/document-management-system-plan.md` (문서관리 시스템 80% 완료) |
|
||
|
|
|
||
|
|
### Git 저장소
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# react (프론트엔드) - 독립 Git 저장소
|
||
|
|
cd /Users/kent/Works/@KD_SAM/SAM/react
|
||
|
|
git status && git branch
|
||
|
|
|
||
|
|
# api (백엔드) - 독립 Git 저장소
|
||
|
|
cd /Users/kent/Works/@KD_SAM/SAM/api
|
||
|
|
git status && git branch
|
||
|
|
```
|
||
|
|
|
||
|
|
> **주의**: SAM/ 루트는 Git 저장소가 아님. api/, mng/, react/ 각각 독립 Git 저장소.
|
||
|
|
|
||
|
|
### 세션 시작 체크리스트
|
||
|
|
|
||
|
|
```
|
||
|
|
1. 이 문서를 읽는다 (📍 현재 진행 상태 섹션 확인)
|
||
|
|
2. react/CLAUDE.md 를 읽는다 (프론트엔드 프로젝트 규칙)
|
||
|
|
3. 마지막 완료 작업 확인 → 다음 작업 결정
|
||
|
|
4. 해당 Phase의 상세 절차(섹션 5)를 읽는다
|
||
|
|
5. 작업 시작 전 사용자에게 "Phase X.X 시작할까요?" 확인
|
||
|
|
```
|
||
|
|
|
||
|
|
### 핵심 파일 (작업 빈도순)
|
||
|
|
|
||
|
|
**Frontend (react)**
|
||
|
|
|
||
|
|
| 파일 | 설명 |
|
||
|
|
|------|------|
|
||
|
|
| `react/src/components/production/WorkerScreen/index.tsx` | 작업자 화면 메인 (중간검사 버튼 핸들러) |
|
||
|
|
| `react/src/components/production/WorkerScreen/InspectionInputModal.tsx` | 중간검사 입력 모달 (개소별 데이터 입력) |
|
||
|
|
| `react/src/components/production/WorkerScreen/types.ts` | InspectionData, WorkItemData, InspectionDataMap 타입 |
|
||
|
|
| `react/src/components/production/WorkerScreen/actions.ts` | 작업자 화면 서버 액션 |
|
||
|
|
| `react/src/components/production/WorkOrders/documents/InspectionReportModal.tsx` | 중간검사 성적서 모달 (문서 래퍼) |
|
||
|
|
| `react/src/components/production/WorkOrders/documents/ScreenInspectionContent.tsx` | 스크린 검사 성적서 콘텐츠 |
|
||
|
|
| `react/src/components/production/WorkOrders/documents/SlatInspectionContent.tsx` | 슬랫 검사 성적서 콘텐츠 |
|
||
|
|
| `react/src/components/production/WorkOrders/documents/BendingInspectionContent.tsx` | 절곡 검사 성적서 콘텐츠 |
|
||
|
|
| `react/src/components/production/WorkOrders/actions.ts` | saveInspectionData 서버 액션 (628-668줄) |
|
||
|
|
| `react/src/components/document-system/configs/qms/index.ts` | QMS 문서 Config 6종 |
|
||
|
|
|
||
|
|
**Backend (api)**
|
||
|
|
|
||
|
|
| 파일 | 설명 |
|
||
|
|
|------|------|
|
||
|
|
| `api/app/Http/Controllers/Api/V1/InspectionController.php` | 검사 CRUD API (89줄) |
|
||
|
|
| `api/app/Services/InspectionService.php` | 검사 비즈니스 로직 (402줄) |
|
||
|
|
| `api/routes/api/v1/production.php` | 생산 관련 라우트 |
|
||
|
|
|
||
|
|
**MNG (양식 관리)**
|
||
|
|
|
||
|
|
| 파일 | 설명 |
|
||
|
|
|------|------|
|
||
|
|
| `mng/app/Models/DocumentTemplate.php` | 양식 템플릿 모델 |
|
||
|
|
| `mng/app/Models/Documents/Document.php` | 문서 인스턴스 모델 |
|
||
|
|
| `mng/resources/views/document-templates/edit.blade.php` | 양식 편집 UI |
|
||
|
|
|
||
|
|
### 현재 코드 구조 (핵심 타입/인터페이스)
|
||
|
|
|
||
|
|
**InspectionData (프론트 - 검사 입력 데이터)**
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// react/src/components/production/WorkerScreen/InspectionInputModal.tsx:35-56
|
||
|
|
export type InspectionProcessType = 'screen' | 'slat' | 'slat_jointbar' | 'bending' | 'bending_wip';
|
||
|
|
|
||
|
|
export interface InspectionData {
|
||
|
|
productName: string;
|
||
|
|
specification: string;
|
||
|
|
bendingStatus?: 'good' | 'bad' | null; // 절곡상태
|
||
|
|
processingStatus?: 'good' | 'bad' | null; // 가공상태
|
||
|
|
sewingStatus?: 'good' | 'bad' | null; // 재봉상태
|
||
|
|
assemblyStatus?: 'good' | 'bad' | null; // 조립상태
|
||
|
|
length?: number | null;
|
||
|
|
width?: number | null;
|
||
|
|
height1?: number | null;
|
||
|
|
height2?: number | null;
|
||
|
|
length3?: number | null;
|
||
|
|
gap4?: number | null;
|
||
|
|
gapStatus?: 'ok' | 'ng' | null;
|
||
|
|
gapPoints?: { left: number | null; right: number | null }[];
|
||
|
|
judgment: 'pass' | 'fail' | null;
|
||
|
|
nonConformingContent: string;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**InspectionDataMap (프론트 - 아이템별 검사 데이터 맵)**
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// react/src/components/production/WorkOrders/documents/InspectionReportModal.tsx:37
|
||
|
|
export type InspectionDataMap = Map<string, InspectionData>;
|
||
|
|
// key: workItem.id (또는 selectedOrder.id), value: InspectionData
|
||
|
|
```
|
||
|
|
|
||
|
|
**WorkItemData (프론트 - 작업 아이템)**
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// react/src/components/production/WorkerScreen/types.ts:32-58
|
||
|
|
export interface WorkItemData {
|
||
|
|
id: string;
|
||
|
|
itemNo: number;
|
||
|
|
itemCode: string;
|
||
|
|
itemName: string;
|
||
|
|
floor: string;
|
||
|
|
code: string;
|
||
|
|
width: number;
|
||
|
|
height: number;
|
||
|
|
quantity: number;
|
||
|
|
processType: ProcessTab; // 'screen' | 'slat' | 'bending'
|
||
|
|
steps: WorkStepData[];
|
||
|
|
isWip?: boolean;
|
||
|
|
isJointBar?: boolean;
|
||
|
|
cuttingInfo?: CuttingInfo; // 스크린 전용
|
||
|
|
slatInfo?: SlatInfo; // 슬랫 전용
|
||
|
|
slatJointBarInfo?: SlatJointBarInfo; // 조인트바 전용
|
||
|
|
bendingInfo?: BendingInfo; // 절곡 전용
|
||
|
|
wipInfo?: WipInfo; // 재공품 전용
|
||
|
|
materialInputs?: MaterialListItem[];
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**WorkOrderItem 모델 (백엔드)**
|
||
|
|
|
||
|
|
```php
|
||
|
|
// api/app/Models/Production/WorkOrderItem.php
|
||
|
|
class WorkOrderItem extends Model {
|
||
|
|
use Auditable, BelongsToTenant;
|
||
|
|
|
||
|
|
protected $fillable = [
|
||
|
|
'tenant_id', 'work_order_id', 'source_order_item_id',
|
||
|
|
'item_id', 'item_name', 'specification',
|
||
|
|
'quantity', 'unit', 'sort_order', 'status', 'options',
|
||
|
|
];
|
||
|
|
|
||
|
|
protected $casts = ['options' => 'array']; // ← JSON 컬럼, inspection_data 저장 대상
|
||
|
|
|
||
|
|
// options['result'] 패턴이 이미 존재 (작업 완료 결과 저장)
|
||
|
|
// 동일 패턴으로 options['inspection_data'] 추가 예정
|
||
|
|
public function getResult(): ?array { return $this->options['result'] ?? null; }
|
||
|
|
public function setResult(array $result): void {
|
||
|
|
$options = $this->options ?? [];
|
||
|
|
$options['result'] = array_merge($options['result'] ?? [], $result);
|
||
|
|
$this->options = $options;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**InspectionReportModal - 공정별 라우팅 로직**
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// react/src/components/production/WorkOrders/documents/InspectionReportModal.tsx:185-201
|
||
|
|
switch (processType) {
|
||
|
|
case 'screen':
|
||
|
|
return <ScreenInspectionContent {...commonProps} />;
|
||
|
|
case 'slat':
|
||
|
|
if (isJointBar || order.items?.some(item => item.productName?.includes('조인트바'))) {
|
||
|
|
return <SlatJointBarInspectionContent {...commonProps} />;
|
||
|
|
}
|
||
|
|
return <SlatInspectionContent {...commonProps} />;
|
||
|
|
case 'bending':
|
||
|
|
return <BendingInspectionContent {...commonProps} />;
|
||
|
|
case 'bending_wip':
|
||
|
|
return <BendingWipInspectionContent {...commonProps} />;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**WorkerScreen - 검사 핸들러 (핵심 흐름)**
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// react/src/components/production/WorkerScreen/index.tsx
|
||
|
|
// 1) 중간검사 입력: handleInspectionClick (802줄) → InspectionInputModal 오픈
|
||
|
|
// 2) 검사 완료: handleInspectionComplete (862줄) → inspectionDataMap에 저장 (메모리만!)
|
||
|
|
// 3) 성적서 보기: handleInspection (851줄) → InspectionReportModal 오픈
|
||
|
|
// - workItems + inspectionDataMap을 props로 전달
|
||
|
|
|
||
|
|
const [inspectionDataMap, setInspectionDataMap] = useState<Map<string, InspectionData>>(new Map());
|
||
|
|
|
||
|
|
const handleInspectionComplete = useCallback((data: InspectionData) => {
|
||
|
|
if (selectedOrder) {
|
||
|
|
setInspectionDataMap((prev) => {
|
||
|
|
const next = new Map(prev);
|
||
|
|
next.set(selectedOrder.id, data); // ← 현재: 메모리에만 저장, API 호출 없음!
|
||
|
|
return next;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}, [selectedOrder]);
|
||
|
|
```
|
||
|
|
|
||
|
|
**기존 saveInspectionData 서버 액션 (미완성)**
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// react/src/components/production/WorkOrders/actions.ts:628-668
|
||
|
|
export async function saveInspectionData(
|
||
|
|
workOrderId: string, processType: string, data: unknown
|
||
|
|
): Promise<{ success: boolean; error?: string }> {
|
||
|
|
// POST /api/v1/work-orders/{workOrderId}/inspection
|
||
|
|
// ⚠️ 문제: 백엔드에 이 엔드포인트가 존재하지 않음!
|
||
|
|
// production.php 라우트에 /work-orders/{id}/inspection 없음
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 백엔드 라우트 구조 (현재)
|
||
|
|
|
||
|
|
```php
|
||
|
|
// api/routes/api/v1/production.php (43-74줄)
|
||
|
|
Route::prefix('work-orders')->group(function () {
|
||
|
|
// 기본 CRUD: index, stats, store, show, update, destroy
|
||
|
|
// 상태 관리: updateStatus, assign, toggleBendingField
|
||
|
|
// 이슈: addIssue, resolveIssue
|
||
|
|
// 품목: updateItemStatus
|
||
|
|
// 자재: materials, registerMaterialInput, materialInputHistory
|
||
|
|
// 단계 진행: stepProgress, toggleStepProgress
|
||
|
|
// ⚠️ 검사(inspection) 관련 라우트 없음 → Phase 1에서 추가 필요
|
||
|
|
});
|
||
|
|
|
||
|
|
// 별도 검사 API (InspectionController) - 범용 검사, 작업지시와 직접 연결 아님
|
||
|
|
Route::prefix('inspections')->group(function () {
|
||
|
|
Route::get('', [InspectionController::class, 'index']); // 목록
|
||
|
|
Route::post('', [InspectionController::class, 'store']); // 생성
|
||
|
|
Route::get('/{id}', [InspectionController::class, 'show']); // 상세
|
||
|
|
// ...
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
### 백엔드 컨트롤러/서비스 구조 (현재)
|
||
|
|
|
||
|
|
```php
|
||
|
|
// WorkOrderController: 18개 메서드 (inspection 관련 없음)
|
||
|
|
// WorkOrderService: 16개 메서드 (1493줄, inspection 관련 없음)
|
||
|
|
// → Phase 1에서 3개 메서드 추가 필요:
|
||
|
|
// storeItemInspection, getInspectionData, getInspectionReport
|
||
|
|
```
|
||
|
|
|
||
|
|
### 문서 템플릿 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, field_key/field_value)
|
||
|
|
└── document_attachments # 첨부 파일
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📍 현재 진행 상태
|
||
|
|
|
||
|
|
| 항목 | 내용 |
|
||
|
|
|------|------|
|
||
|
|
| **마지막 완료 작업** | 분석 완료 - 중간검사 모달/문서관리 시스템/성적서 컴포넌트 전체 분석 |
|
||
|
|
| **다음 작업** | Phase 1.1 - 백엔드 API 설계 |
|
||
|
|
| **진행률** | 0/14 (0%) |
|
||
|
|
| **마지막 업데이트** | 2026-02-07 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. 개요
|
||
|
|
|
||
|
|
### 1.1 배경
|
||
|
|
|
||
|
|
현재 중간검사 시스템은 다음 상태입니다:
|
||
|
|
|
||
|
|
**개소별 검사 입력 (InspectionInputModal)**
|
||
|
|
- 스타일 수입검사 모달과 통일 완료 (2026-02-07)
|
||
|
|
- 공정별 입력 항목: 스크린(6항목), 슬랫(5항목), 조인트바(6항목), 절곡(3항목+간격5포인트), 재공품(3항목+간격)
|
||
|
|
- 데이터 저장: **프론트 메모리(InspectionDataMap)에만 보관**, 백엔드 저장 미구현
|
||
|
|
|
||
|
|
**검사 성적서 보기 (InspectionReportModal)**
|
||
|
|
- 4종 하드코딩 컴포넌트: Screen/Slat/Bending/BendingWip InspectionContent
|
||
|
|
- 조인트바 자동 감지 (SlatJointBarInspectionContent)
|
||
|
|
- 문서 템플릿 시스템 미활용 (레이아웃 코드 내 고정)
|
||
|
|
- workItems 기반 동적 행 생성 + inspectionDataMap에서 데이터 매핑
|
||
|
|
|
||
|
|
**문서관리 시스템 (80% 완료)**
|
||
|
|
- mng.sam.kr/document-templates에서 양식 CRUD 가능
|
||
|
|
- API: documents/resolve (카테고리+아이템 기반 조회), documents/upsert (저장)
|
||
|
|
- EAV 패턴: document_data 테이블 (field_key/field_value)
|
||
|
|
- 수입검사 성적서는 이미 문서관리 시스템 연동 완료
|
||
|
|
|
||
|
|
**문제점**
|
||
|
|
1. 개소별 검사 데이터가 프론트 메모리에만 존재 → 새로고침 시 소실
|
||
|
|
2. 성적서 레이아웃이 하드코딩 → 양식 변경 시 코드 수정 필요
|
||
|
|
3. 검사 이력 관리 불가 → 언제 누가 어떤 데이터를 입력했는지 추적 불가
|
||
|
|
|
||
|
|
### 1.2 핵심 원칙
|
||
|
|
|
||
|
|
```
|
||
|
|
┌─────────────────────────────────────────────────────────────────┐
|
||
|
|
│ 🎯 하이브리드 방식 │
|
||
|
|
├─────────────────────────────────────────────────────────────────┤
|
||
|
|
│ 1. 개소별 데이터 → work_order_items.options JSON에 저장 │
|
||
|
|
│ 2. 성적서 레이아웃 → 문서 템플릿 시스템(mng)에서 관리 │
|
||
|
|
│ 3. 성적서 보기 → 템플릿 레이아웃 + 개소 데이터 결합하여 렌더링 │
|
||
|
|
│ 4. 기존 InspectionContent 컴포넌트 → Config 기반으로 점진 전환 │
|
||
|
|
└─────────────────────────────────────────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
### 1.3 수입검사 성적서와의 비교
|
||
|
|
|
||
|
|
| 구분 | 수입검사 성적서 | 중간검사 성적서 (목표) |
|
||
|
|
|------|----------------|----------------------|
|
||
|
|
| **데이터 소스** | 1입고 = 1문서 | N개소 = 1문서 (합산) |
|
||
|
|
| **데이터 수집** | 한 번에 입력 | 개소별로 따로 입력 후 합산 |
|
||
|
|
| **데이터 저장** | document_data (EAV) | work_order_items.options (JSON) |
|
||
|
|
| **레이아웃** | 문서 템플릿 시스템 | 문서 템플릿 시스템 (동일) |
|
||
|
|
| **측정 항목** | 자재별 고정 | 공정별 다름 (스크린/슬랫/절곡/조인트바) |
|
||
|
|
| **자동 판정** | 있음 (N1~Nn 탭) | 있음 (행별 + 종합) |
|
||
|
|
| **문서 유형** | 1종 | 5종 (스크린/슬랫/조인트바/절곡/재공품) |
|
||
|
|
|
||
|
|
### 1.4 변경 승인 정책
|
||
|
|
|
||
|
|
| 분류 | 예시 | 승인 |
|
||
|
|
|------|------|------|
|
||
|
|
| ✅ 즉시 가능 | 프론트 컴포넌트 수정, 서버 액션 추가, 타입 정의 | 불필요 |
|
||
|
|
| ⚠️ 컨펌 필요 | API 엔드포인트 추가, work_order_items.options 구조 변경, 문서 템플릿 등록 | **필수** |
|
||
|
|
| 🔴 금지 | 테이블 구조 변경, 기존 API 삭제, 수입검사 로직 변경 | 별도 협의 |
|
||
|
|
|
||
|
|
### 1.5 준수 규칙
|
||
|
|
|
||
|
|
- `docs/quickstart/quick-start.md` - 빠른 시작 가이드
|
||
|
|
- `docs/standards/quality-checklist.md` - 품질 체크리스트
|
||
|
|
- `react/CLAUDE.md` - 프론트엔드 프로젝트 규칙
|
||
|
|
- `docs/plans/document-management-system-plan.md` - 문서관리 시스템 계획서
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. 현황 분석
|
||
|
|
|
||
|
|
### 2.1 현재 동작하는 검사 흐름 (문제점 포함)
|
||
|
|
|
||
|
|
```
|
||
|
|
[현재 흐름 - 데이터가 메모리에만 존재]
|
||
|
|
|
||
|
|
1. 작업자 화면 진입 (dev.sam.kr/production/worker-screen)
|
||
|
|
↓
|
||
|
|
2. 작업지시 선택 → 개소(아이템) 카드 목록 표시
|
||
|
|
↓
|
||
|
|
3. 개소 카드의 "중간검사" 단계(pill) 클릭
|
||
|
|
↓ handleInspectionClick (index.tsx:802)
|
||
|
|
4. InspectionInputModal 오픈 (공정별 입력 항목)
|
||
|
|
↓ 작업자가 검사 데이터 입력 후 "검사 완료"
|
||
|
|
5. handleInspectionComplete (index.tsx:862)
|
||
|
|
↓ inspectionDataMap.set(selectedOrder.id, data)
|
||
|
|
⚠️ 메모리에만 저장! → 새로고침하면 소실
|
||
|
|
↓
|
||
|
|
6. "검사성적서 보기" 버튼 클릭
|
||
|
|
↓ handleInspection (index.tsx:851)
|
||
|
|
7. InspectionReportModal 오픈
|
||
|
|
- workItems + inspectionDataMap props 전달
|
||
|
|
- 공정별 InspectionContent 컴포넌트 렌더링
|
||
|
|
↓
|
||
|
|
8. DocumentViewer로 문서 형태 표시/인쇄
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.2 기존 코드에서 활용할 수 있는 패턴
|
||
|
|
|
||
|
|
| 패턴 | 위치 | 설명 |
|
||
|
|
|------|------|------|
|
||
|
|
| `options['result']` 패턴 | WorkOrderItem.php:119-132 | options JSON에 구조화된 데이터 저장/조회 |
|
||
|
|
| `saveInspectionData` 서버 액션 | WorkOrders/actions.ts:628-668 | POST 구조 이미 존재 (백엔드 미구현) |
|
||
|
|
| `InspectionDataMap` | InspectionReportModal.tsx:37 | 아이템ID→검사데이터 Map 구조 |
|
||
|
|
| `InspectionContentRef.getInspectionData()` | InspectionReportModal.tsx:143 | 성적서에서 데이터 추출 인터페이스 |
|
||
|
|
| `DocumentViewer` preset="inspection" | InspectionReportModal.tsx:216 | 검사 문서 뷰어 프리셋 |
|
||
|
|
|
||
|
|
### 2.3 관련 API 현황
|
||
|
|
|
||
|
|
| API | 상태 | 비고 |
|
||
|
|
|-----|------|------|
|
||
|
|
| `GET /work-orders` | ✅ 존재 | 목록 조회 |
|
||
|
|
| `GET /work-orders/{id}` | ✅ 존재 | 상세 (items 포함) |
|
||
|
|
| `PATCH /work-orders/{id}/items/{itemId}/status` | ✅ 존재 | 품목 상태 변경 |
|
||
|
|
| `POST /work-orders/{id}/inspection` | ❌ 없음 | saveInspectionData가 호출하려는 URL |
|
||
|
|
| `POST /work-orders/{id}/items/{itemId}/inspection` | ❌ 없음 | Phase 1.2에서 구현 |
|
||
|
|
| `GET /work-orders/{id}/inspection-data` | ❌ 없음 | Phase 1.3에서 구현 |
|
||
|
|
| `GET /work-orders/{id}/inspection-report` | ❌ 없음 | Phase 1.4에서 구현 |
|
||
|
|
| `GET /documents/resolve` | ✅ 존재 | 문서 템플릿 조회 (Phase 1.4에서 활용) |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. 대상 범위
|
||
|
|
|
||
|
|
### Phase 의존 관계
|
||
|
|
|
||
|
|
```
|
||
|
|
Phase 1 (백엔드 API)
|
||
|
|
↓ Phase 2가 Phase 1에 의존 (API가 있어야 프론트 연동)
|
||
|
|
Phase 2 (프론트 저장 연동)
|
||
|
|
↓ Phase 3은 Phase 1-2와 독립 (mng에서 양식 등록)
|
||
|
|
Phase 3 (mng 템플릿 등록)
|
||
|
|
↓ Phase 4가 Phase 1+3에 의존 (API + 템플릿 모두 필요)
|
||
|
|
Phase 4 (프론트 성적서 연동)
|
||
|
|
```
|
||
|
|
|
||
|
|
### Phase 1: 백엔드 - 개소별 검사 데이터 저장 API
|
||
|
|
|
||
|
|
| # | 작업 항목 | 상태 | 완료 기준 | 비고 |
|
||
|
|
|---|----------|:----:|----------|------|
|
||
|
|
| 1.1 | API 엔드포인트 설계 | ⏳ | 엔드포인트 목록 + 요청/응답 스키마 확정 | ⚠️ 컨펌 필요 |
|
||
|
|
| 1.2 | 개소별 검사 데이터 저장 API 구현 | ⏳ | POST /work-orders/{id}/items/{itemId}/inspection 동작 | work_order_items.options에 inspection_data 필드 추가 |
|
||
|
|
| 1.3 | 개소별 검사 데이터 조회 API 구현 | ⏳ | GET /work-orders/{id}/inspection-data 동작 | 전체 개소 검사 데이터 한번에 반환 |
|
||
|
|
| 1.4 | 성적서 문서 데이터 조회 API 구현 | ⏳ | GET /work-orders/{id}/inspection-report 동작 | 템플릿 + 개소 데이터 결합 응답 |
|
||
|
|
|
||
|
|
### Phase 2: 프론트 - 개소별 검사 데이터 저장 연동
|
||
|
|
|
||
|
|
| # | 작업 항목 | 상태 | 완료 기준 | 비고 |
|
||
|
|
|---|----------|:----:|----------|------|
|
||
|
|
| 2.1 | 서버 액션 추가 (저장/조회) | ⏳ | saveItemInspection, getInspectionData 서버 액션 동작 | |
|
||
|
|
| 2.2 | InspectionInputModal - 저장 연동 | ⏳ | "검사 완료" 클릭 시 API 호출 + 성공/실패 피드백 | |
|
||
|
|
| 2.3 | WorkerScreen - 저장된 데이터 로드 | ⏳ | 화면 진입 시 기존 검사 데이터 자동 로드 | inspectionDataMap 초기화 |
|
||
|
|
| 2.4 | InspectionInputModal - 기존 데이터 표시 | ⏳ | 이미 검사한 개소 재클릭 시 저장된 데이터 표시 | |
|
||
|
|
|
||
|
|
### Phase 3: 문서 템플릿 등록 (mng)
|
||
|
|
|
||
|
|
| # | 작업 항목 | 상태 | 완료 기준 | 비고 |
|
||
|
|
|---|----------|:----:|----------|------|
|
||
|
|
| 3.1 | 스크린 중간검사 양식 등록 | ⏳ | mng.sam.kr/document-templates에서 양식 확인 | ⚠️ 컨펌 필요 |
|
||
|
|
| 3.2 | 슬랫 중간검사 양식 등록 | ⏳ | 위와 동일 | |
|
||
|
|
| 3.3 | 절곡 중간검사 양식 등록 | ⏳ | 위와 동일 | |
|
||
|
|
| 3.4 | 조인트바 중간검사 양식 등록 | ⏳ | 위와 동일 | |
|
||
|
|
|
||
|
|
### Phase 4: 프론트 - 성적서 보기 템플릿 연동
|
||
|
|
|
||
|
|
| # | 작업 항목 | 상태 | 완료 기준 | 비고 |
|
||
|
|
|---|----------|:----:|----------|------|
|
||
|
|
| 4.1 | InspectionReportModal - API 연동 | ⏳ | 템플릿 + 검사 데이터 API에서 로드 | |
|
||
|
|
| 4.2 | InspectionContent 컴포넌트 리팩토링 | ⏳ | Config 기반으로 전환 (기존 하드코딩 제거) | 점진적 전환 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. 아키텍처 설계
|
||
|
|
|
||
|
|
### 3.1 데이터 흐름
|
||
|
|
|
||
|
|
```
|
||
|
|
[개소별 중간검사] [검사 성적서 보기]
|
||
|
|
|
||
|
|
작업자 화면 작업자 화면
|
||
|
|
↓ "중간검사" 클릭 ↓ "검사성적서보기" 클릭
|
||
|
|
InspectionInputModal InspectionReportModal
|
||
|
|
↓ 검사 완료 ↓
|
||
|
|
POST /work-orders/{id}/ GET /work-orders/{id}/
|
||
|
|
items/{itemId}/inspection inspection-report
|
||
|
|
↓ ↓
|
||
|
|
work_order_items.options {
|
||
|
|
.inspection_data = { template: { 레이아웃 JSON },
|
||
|
|
processingStatus: 'good', items: [
|
||
|
|
sewingStatus: 'good', { itemId, itemName, inspectionData },
|
||
|
|
length: 1200, { itemId, itemName, inspectionData },
|
||
|
|
judgment: 'pass', ...
|
||
|
|
... ],
|
||
|
|
} summary: { total, pass, fail }
|
||
|
|
}
|
||
|
|
↓
|
||
|
|
공정별 InspectionContent 렌더링
|
||
|
|
(템플릿 레이아웃 + 개소 데이터 결합)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.2 work_order_items.options JSON 구조 (확장)
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"floor": "3F",
|
||
|
|
"code": "SC-001",
|
||
|
|
"width": 1200,
|
||
|
|
"height": 800,
|
||
|
|
"cutting_info": { ... },
|
||
|
|
"slat_info": { ... },
|
||
|
|
"bending_info": { ... },
|
||
|
|
"wip_info": { ... },
|
||
|
|
"inspection_data": {
|
||
|
|
"inspected_at": "2026-02-07T14:30:00Z",
|
||
|
|
"inspected_by": "user_id",
|
||
|
|
"inspected_by_name": "홍길동",
|
||
|
|
"process_type": "screen",
|
||
|
|
"data": {
|
||
|
|
"processingStatus": "good",
|
||
|
|
"sewingStatus": "good",
|
||
|
|
"assemblyStatus": "good",
|
||
|
|
"length": 1200,
|
||
|
|
"width": 800,
|
||
|
|
"gapStatus": "ok",
|
||
|
|
"gapPoints": [
|
||
|
|
{ "left": 5.0, "right": 5.0 }
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"judgment": "pass",
|
||
|
|
"non_conforming_content": ""
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.3 API 설계
|
||
|
|
|
||
|
|
**1) 개소별 검사 데이터 저장**
|
||
|
|
|
||
|
|
```
|
||
|
|
POST /api/v1/work-orders/{workOrderId}/items/{itemId}/inspection
|
||
|
|
|
||
|
|
Request:
|
||
|
|
{
|
||
|
|
"process_type": "screen",
|
||
|
|
"inspection_data": {
|
||
|
|
"processingStatus": "good",
|
||
|
|
"sewingStatus": "good",
|
||
|
|
"assemblyStatus": "good",
|
||
|
|
"length": 1200,
|
||
|
|
"width": 800,
|
||
|
|
"gapStatus": "ok",
|
||
|
|
"gapPoints": [{ "left": 5.0, "right": 5.0 }]
|
||
|
|
},
|
||
|
|
"judgment": "pass",
|
||
|
|
"non_conforming_content": ""
|
||
|
|
}
|
||
|
|
|
||
|
|
Response:
|
||
|
|
{
|
||
|
|
"success": true,
|
||
|
|
"data": {
|
||
|
|
"item_id": "item-uuid",
|
||
|
|
"inspection_data": { ... },
|
||
|
|
"inspected_at": "2026-02-07T14:30:00Z"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**2) 작업지시 전체 검사 데이터 조회**
|
||
|
|
|
||
|
|
```
|
||
|
|
GET /api/v1/work-orders/{workOrderId}/inspection-data
|
||
|
|
|
||
|
|
Response:
|
||
|
|
{
|
||
|
|
"success": true,
|
||
|
|
"data": {
|
||
|
|
"work_order_id": "wo-uuid",
|
||
|
|
"process_type": "screen",
|
||
|
|
"items": [
|
||
|
|
{
|
||
|
|
"item_id": "item-1",
|
||
|
|
"item_name": "SC-001-3F",
|
||
|
|
"has_inspection": true,
|
||
|
|
"inspection_data": { ... },
|
||
|
|
"judgment": "pass",
|
||
|
|
"inspected_at": "2026-02-07T14:30:00Z",
|
||
|
|
"inspected_by_name": "홍길동"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"item_id": "item-2",
|
||
|
|
"item_name": "SC-002-3F",
|
||
|
|
"has_inspection": false,
|
||
|
|
"inspection_data": null,
|
||
|
|
"judgment": null,
|
||
|
|
"inspected_at": null,
|
||
|
|
"inspected_by_name": null
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"summary": {
|
||
|
|
"total": 6,
|
||
|
|
"inspected": 4,
|
||
|
|
"pass": 3,
|
||
|
|
"fail": 1,
|
||
|
|
"pending": 2
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**3) 검사 성적서 데이터 조회 (문서 형태)**
|
||
|
|
|
||
|
|
```
|
||
|
|
GET /api/v1/work-orders/{workOrderId}/inspection-report
|
||
|
|
|
||
|
|
Response:
|
||
|
|
{
|
||
|
|
"success": true,
|
||
|
|
"data": {
|
||
|
|
"work_order_id": "wo-uuid",
|
||
|
|
"process_type": "screen",
|
||
|
|
"template": {
|
||
|
|
"id": "template-uuid",
|
||
|
|
"title": "스크린 중간검사 성적서",
|
||
|
|
"approval_lines": [...],
|
||
|
|
"basic_fields": [...],
|
||
|
|
"sections": [...],
|
||
|
|
"columns": [...]
|
||
|
|
},
|
||
|
|
"document_data": {
|
||
|
|
"basic_fields": {
|
||
|
|
"product_name": "블라인드 A형",
|
||
|
|
"specification": "1200x800",
|
||
|
|
"lot_no": "LOT-2026-001",
|
||
|
|
"inspection_date": "2026-02-07",
|
||
|
|
"inspector": "홍길동"
|
||
|
|
},
|
||
|
|
"inspection_rows": [
|
||
|
|
{
|
||
|
|
"row_no": 1,
|
||
|
|
"item_id": "item-1",
|
||
|
|
"item_name": "SC-001-3F",
|
||
|
|
"processing_status": "양호",
|
||
|
|
"sewing_status": "양호",
|
||
|
|
"assembly_status": "양호",
|
||
|
|
"length_design": 1200,
|
||
|
|
"length_measured": 1200,
|
||
|
|
"width_design": 800,
|
||
|
|
"width_measured": 800,
|
||
|
|
"gap_standard": "5±1",
|
||
|
|
"gap_result": "OK",
|
||
|
|
"judgment": "적"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"summary": {
|
||
|
|
"total": 6,
|
||
|
|
"pass": 5,
|
||
|
|
"fail": 1,
|
||
|
|
"overall_judgment": "합격",
|
||
|
|
"non_conforming_content": "item-3: 길이 규격 초과"
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"inspection_setting": {
|
||
|
|
"schematic_image": "/img/inspection/screen-schematic.png",
|
||
|
|
"inspection_standard_image": "/img/inspection/screen-standard.png"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.4 공정별 검사 항목 매핑
|
||
|
|
|
||
|
|
**스크린 (screen)**
|
||
|
|
|
||
|
|
| 검사항목 | 입력 타입 | options.inspection_data 키 | 성적서 컬럼 |
|
||
|
|
|---------|----------|---------------------------|------------|
|
||
|
|
| 가공상태 결모양 | good/bad | processingStatus | 가공상태 |
|
||
|
|
| 재봉상태 결모양 | good/bad | sewingStatus | 재봉상태 |
|
||
|
|
| 조립상태 | good/bad | assemblyStatus | 조립상태 |
|
||
|
|
| 길이 | number | length | 길이 (도면치수 vs 측정값) |
|
||
|
|
| 나비 | number | width | 나비 (도면치수 vs 측정값) |
|
||
|
|
| 간격 | ok/ng | gapStatus | 간격 (기준치 vs OK/NG) |
|
||
|
|
|
||
|
|
**슬랫 (slat)**
|
||
|
|
|
||
|
|
| 검사항목 | 입력 타입 | options.inspection_data 키 | 성적서 컬럼 |
|
||
|
|
|---------|----------|---------------------------|------------|
|
||
|
|
| 가공상태 | good/bad | processingStatus | 가공상태 |
|
||
|
|
| 조립상태 | good/bad | assemblyStatus | 조립상태 |
|
||
|
|
| ① 높이 | number | height1 | 높이① (16.5±1) |
|
||
|
|
| ② 높이 | number | height2 | 높이② (14.5±1) |
|
||
|
|
| 길이 | number | length | 길이 |
|
||
|
|
|
||
|
|
**조인트바 (slat_jointbar)**
|
||
|
|
|
||
|
|
| 검사항목 | 입력 타입 | options.inspection_data 키 | 성적서 컬럼 |
|
||
|
|
|---------|----------|---------------------------|------------|
|
||
|
|
| 가공상태 | good/bad | processingStatus | 가공상태 |
|
||
|
|
| 조립상태 | good/bad | assemblyStatus | 조립상태 |
|
||
|
|
| ① 높이 | number | height1 | 높이① |
|
||
|
|
| ② 높이 | number | height2 | 높이② |
|
||
|
|
| ③ 길이 | number | length | 길이 |
|
||
|
|
| ④ 간격 | number | gapValue | 간격 |
|
||
|
|
|
||
|
|
**절곡 (bending)**
|
||
|
|
|
||
|
|
| 검사항목 | 입력 타입 | options.inspection_data 키 | 성적서 컬럼 |
|
||
|
|
|---------|----------|---------------------------|------------|
|
||
|
|
| 절곡상태 | good/bad | bendingStatus | 절곡상태 |
|
||
|
|
| 길이 | number | length | 길이 |
|
||
|
|
| 간격 (5포인트) | number x 10 | gapPoints[].left/right | 간격 좌1~좌5, 우1~우5 |
|
||
|
|
|
||
|
|
**재공품 (bending_wip)**
|
||
|
|
|
||
|
|
| 검사항목 | 입력 타입 | options.inspection_data 키 | 성적서 컬럼 |
|
||
|
|
|---------|----------|---------------------------|------------|
|
||
|
|
| 절곡상태 | good/bad | bendingStatus | 절곡상태 |
|
||
|
|
| 길이 | number | length | 길이 |
|
||
|
|
| 나비 | number | width | 나비 |
|
||
|
|
| 간격 | ok/ng | gapStatus | 간격 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. 기술 결정사항
|
||
|
|
|
||
|
|
### 4.1 확정 결정
|
||
|
|
|
||
|
|
| # | 결정 사항 | 선택 | 근거 |
|
||
|
|
|---|----------|------|------|
|
||
|
|
| 1 | 데이터 저장 위치 | work_order_items.options JSON | 이미 공정별 데이터(cutting_info, slat_info 등) 저장에 사용 중, 추가 테이블 불필요 |
|
||
|
|
| 2 | 레이아웃 관리 | 문서 템플릿 시스템 (mng) | 문서관리 시스템 80% 완료, 양식 변경 시 코드 수정 없이 가능 |
|
||
|
|
| 3 | 성적서 렌더링 | 기존 InspectionContent 컴포넌트 유지 + API 데이터 주입 | 이미 동작하는 렌더링 로직 활용, 점진적으로 Config 기반 전환 |
|
||
|
|
| 4 | 자동 판정 로직 | 프론트엔드에서 계산 (현재 방식 유지) | 공정별 판정 기준이 프론트에 이미 구현됨 |
|
||
|
|
| 5 | 검사 이력 | inspection_data에 inspected_at, inspected_by 포함 | 별도 이력 테이블 불필요, JSON 내에서 추적 |
|
||
|
|
|
||
|
|
### 4.2 검토 필요 항목
|
||
|
|
|
||
|
|
| # | 항목 | 선택지 | 현재 판단 | 비고 |
|
||
|
|
|---|------|--------|----------|------|
|
||
|
|
| 1 | Phase 3 (템플릿 등록) 시점 | A) Phase 1-2와 병행 / B) Phase 1-2 완료 후 | B | Phase 1-2로 데이터 저장/조회 먼저 안정화 |
|
||
|
|
| 2 | 검사 기준 이미지 관리 | A) mng에서 등록 / B) API에서 등록 | A | 문서관리 시스템 계획서 Phase 3.4에서 이미 처리 |
|
||
|
|
| 3 | 기존 하드코딩 컴포넌트 전환 범위 | A) 전체 전환 / B) 점진적 전환 | B | Phase 4에서 점진적 전환, 기존 기능 유지 우선 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 6. 상세 작업 절차
|
||
|
|
|
||
|
|
### Phase 1: 백엔드 - 개소별 검사 데이터 저장 API
|
||
|
|
|
||
|
|
#### 1.1 API 엔드포인트 설계
|
||
|
|
|
||
|
|
**작업 내용:**
|
||
|
|
1. `api/routes/api/v1/production.php`에 라우트 추가:
|
||
|
|
- `POST /work-orders/{workOrderId}/items/{itemId}/inspection`
|
||
|
|
- `GET /work-orders/{workOrderId}/inspection-data`
|
||
|
|
- `GET /work-orders/{workOrderId}/inspection-report`
|
||
|
|
2. 요청/응답 스키마 확정 (섹션 3.3 참조)
|
||
|
|
3. FormRequest 클래스 생성
|
||
|
|
|
||
|
|
**관련 파일:**
|
||
|
|
- `api/routes/api/v1/production.php` (라우트 추가)
|
||
|
|
- `api/app/Http/Requests/Api/V1/` (FormRequest 생성)
|
||
|
|
|
||
|
|
#### 1.2 개소별 검사 데이터 저장 API 구현
|
||
|
|
|
||
|
|
**작업 내용:**
|
||
|
|
1. WorkOrderController에 `storeItemInspection` 메서드 추가
|
||
|
|
2. WorkOrderService에 `saveItemInspection` 메서드 추가:
|
||
|
|
- work_order_items 조회 (workOrderId + itemId)
|
||
|
|
- options JSON에서 기존 데이터 읽기
|
||
|
|
- inspection_data 필드 추가/업데이트
|
||
|
|
- inspected_at, inspected_by 자동 기록
|
||
|
|
3. 유효성 검증: process_type 필수, inspection_data 공정별 스키마 검증
|
||
|
|
|
||
|
|
**관련 파일:**
|
||
|
|
- `api/app/Http/Controllers/Api/V1/WorkOrderController.php`
|
||
|
|
- `api/app/Services/WorkOrderService.php`
|
||
|
|
|
||
|
|
#### 1.3 개소별 검사 데이터 조회 API 구현
|
||
|
|
|
||
|
|
**작업 내용:**
|
||
|
|
1. WorkOrderController에 `getInspectionData` 메서드 추가
|
||
|
|
2. WorkOrderService에 `getInspectionData` 메서드 추가:
|
||
|
|
- 해당 작업지시의 모든 work_order_items 조회
|
||
|
|
- 각 item의 options.inspection_data 추출
|
||
|
|
- 요약 정보 계산 (total, inspected, pass, fail, pending)
|
||
|
|
|
||
|
|
#### 1.4 성적서 문서 데이터 조회 API 구현
|
||
|
|
|
||
|
|
**작업 내용:**
|
||
|
|
1. WorkOrderController에 `getInspectionReport` 메서드 추가
|
||
|
|
2. WorkOrderService에 `getInspectionReport` 메서드 추가:
|
||
|
|
- 공정 타입에 맞는 문서 템플릿 조회 (documents/resolve API 활용)
|
||
|
|
- work_order_items의 inspection_data 수집
|
||
|
|
- 템플릿 레이아웃 + 검사 데이터 + 기본 정보 결합
|
||
|
|
- inspection_setting (도해/검사기준 이미지) 포함
|
||
|
|
|
||
|
|
### Phase 2: 프론트 - 개소별 검사 데이터 저장 연동
|
||
|
|
|
||
|
|
#### 2.1 서버 액션 추가
|
||
|
|
|
||
|
|
**작업 내용:**
|
||
|
|
1. `react/src/components/production/WorkerScreen/actions.ts`에 추가:
|
||
|
|
- `saveItemInspection(workOrderId, itemId, data)` - 개소별 저장
|
||
|
|
- `getWorkOrderInspectionData(workOrderId)` - 전체 검사 데이터 조회
|
||
|
|
- `getInspectionReport(workOrderId)` - 성적서 데이터 조회
|
||
|
|
|
||
|
|
**관련 파일:**
|
||
|
|
- `react/src/components/production/WorkerScreen/actions.ts`
|
||
|
|
|
||
|
|
#### 2.2 InspectionInputModal - 저장 연동
|
||
|
|
|
||
|
|
**작업 내용:**
|
||
|
|
1. onComplete 콜백에서 saveItemInspection 서버 액션 호출
|
||
|
|
2. 저장 성공/실패 toast 알림
|
||
|
|
3. 저장 중 로딩 상태 표시
|
||
|
|
4. 에러 시 재시도 가능
|
||
|
|
|
||
|
|
**관련 파일:**
|
||
|
|
- `react/src/components/production/WorkerScreen/InspectionInputModal.tsx`
|
||
|
|
- `react/src/components/production/WorkerScreen/index.tsx` (handleInspectionClick)
|
||
|
|
|
||
|
|
#### 2.3 WorkerScreen - 저장된 데이터 로드
|
||
|
|
|
||
|
|
**작업 내용:**
|
||
|
|
1. 화면 진입 시 getWorkOrderInspectionData 호출
|
||
|
|
2. 응답 데이터로 inspectionDataMap 초기화
|
||
|
|
3. 이미 검사 완료된 개소 시각적 표시 (아이콘/배지)
|
||
|
|
|
||
|
|
**관련 파일:**
|
||
|
|
- `react/src/components/production/WorkerScreen/index.tsx`
|
||
|
|
|
||
|
|
#### 2.4 InspectionInputModal - 기존 데이터 표시
|
||
|
|
|
||
|
|
**작업 내용:**
|
||
|
|
1. inspectionDataMap에 해당 itemId 데이터가 있으면 폼에 자동 채움
|
||
|
|
2. 기존 검사 데이터 수정 가능 (재검사)
|
||
|
|
3. 최초 검사 vs 재검사 구분 표시
|
||
|
|
|
||
|
|
**관련 파일:**
|
||
|
|
- `react/src/components/production/WorkerScreen/InspectionInputModal.tsx`
|
||
|
|
|
||
|
|
### Phase 3: 문서 템플릿 등록 (mng)
|
||
|
|
|
||
|
|
#### 3.1~3.4 공정별 양식 등록
|
||
|
|
|
||
|
|
**작업 내용 (공정별 동일 패턴):**
|
||
|
|
1. mng.sam.kr/document-templates에서 새 양식 생성
|
||
|
|
2. 카테고리: `intermediate-inspection` / 서브카테고리: `screen` (또는 slat/bending/jointbar)
|
||
|
|
3. 결재라인 설정: 작성자 → 검토 → 승인
|
||
|
|
4. 기본필드: 제품명, 규격, 수주처, 현장명, LOT NO, 검사일자, 검사자
|
||
|
|
5. 섹션1: 중간검사 기준서 (도해 이미지 + 검사항목 테이블)
|
||
|
|
6. 섹션2: 중간검사 DATA (동적 행, 공정별 컬럼 정의)
|
||
|
|
7. 섹션3: 부적합 내용 + 종합 판정
|
||
|
|
8. 도해/검사기준 이미지 등록
|
||
|
|
|
||
|
|
### Phase 4: 프론트 - 성적서 보기 템플릿 연동
|
||
|
|
|
||
|
|
#### 4.1 InspectionReportModal - API 연동
|
||
|
|
|
||
|
|
**작업 내용:**
|
||
|
|
1. getInspectionReport 서버 액션으로 데이터 로드
|
||
|
|
2. 템플릿 레이아웃 정보 활용 (결재라인, 기본필드, 섹션 구조)
|
||
|
|
3. 기존 props 기반 데이터 → API 응답 데이터로 전환
|
||
|
|
4. 로딩/에러 상태 처리
|
||
|
|
|
||
|
|
**관련 파일:**
|
||
|
|
- `react/src/components/production/WorkOrders/documents/InspectionReportModal.tsx`
|
||
|
|
|
||
|
|
#### 4.2 InspectionContent 컴포넌트 리팩토링
|
||
|
|
|
||
|
|
**작업 내용:**
|
||
|
|
1. 기존 하드코딩된 레이아웃을 템플릿 데이터 기반으로 전환
|
||
|
|
2. 공통 렌더링 로직 추출 (테이블 생성, 판정 로직, 결재란)
|
||
|
|
3. 공정별 차이점만 Config로 분리
|
||
|
|
4. 기존 기능 100% 유지 (회귀 방지)
|
||
|
|
|
||
|
|
**관련 파일:**
|
||
|
|
- `react/src/components/production/WorkOrders/documents/ScreenInspectionContent.tsx`
|
||
|
|
- `react/src/components/production/WorkOrders/documents/SlatInspectionContent.tsx`
|
||
|
|
- `react/src/components/production/WorkOrders/documents/BendingInspectionContent.tsx`
|
||
|
|
- `react/src/components/production/WorkOrders/documents/BendingWipInspectionContent.tsx`
|
||
|
|
- `react/src/components/production/WorkOrders/documents/SlatJointBarInspectionContent.tsx`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 7. 컨펌 대기 목록
|
||
|
|
|
||
|
|
| # | 항목 | 변경 내용 | 영향 범위 | 상태 |
|
||
|
|
|---|------|----------|----------|------|
|
||
|
|
| 1 | API 엔드포인트 3개 추가 | work-orders/{id}/items/{itemId}/inspection, inspection-data, inspection-report | api | ⏳ Phase 1.1에서 확정 |
|
||
|
|
| 2 | work_order_items.options 구조 확장 | inspection_data 필드 추가 | api, react | ⏳ Phase 1.2에서 확정 |
|
||
|
|
| 3 | 중간검사 문서 템플릿 4종 등록 | mng 양식 관리에서 등록 | mng | ⏳ Phase 3에서 확정 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 8. 변경 이력
|
||
|
|
|
||
|
|
| 날짜 | 항목 | 변경 내용 | 파일 | 승인 |
|
||
|
|
|------|------|----------|------|------|
|
||
|
|
| 2026-02-07 | 초안 | 계획 문서 초안 작성 | - | - |
|
||
|
|
| 2026-02-07 | 보완 | 자기완결성 보강: Git 정보, 코드 스니펫(타입/모델/라우트/핸들러), 현황 분석(동작 흐름/활용 패턴/API 현황), Phase 의존 관계 추가 | - | - |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 9. 참고 문서
|
||
|
|
|
||
|
|
- **문서관리 시스템 계획**: `docs/plans/document-management-system-plan.md` (80% 완료)
|
||
|
|
- **수입검사 양식 계획**: `docs/plans/incoming-inspection-templates-plan.md`
|
||
|
|
- **수입검사 연동 계획**: `docs/plans/incoming-inspection-document-integration-plan.md`
|
||
|
|
- **DB 스키마**: `docs/specs/database-schema.md`
|
||
|
|
- **빠른 시작**: `docs/quickstart/quick-start.md`
|
||
|
|
- **품질 체크리스트**: `docs/standards/quality-checklist.md`
|
||
|
|
|
||
|
|
### 기존 코드 참조
|
||
|
|
|
||
|
|
- **수입검사 성적서 (참고 모델)**: `react/src/components/material/ReceivingManagement/ImportInspectionInputModal.tsx`
|
||
|
|
- **문서 뷰어**: `react/src/components/document-system/DocumentViewer.tsx`
|
||
|
|
- **QMS Config**: `react/src/components/document-system/configs/qms/index.ts`
|
||
|
|
- **검사 서비스**: `api/app/Services/InspectionService.php`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 10. 검증 결과
|
||
|
|
|
||
|
|
> 작업 완료 후 이 섹션에 검증 결과 추가
|
||
|
|
|
||
|
|
### 9.1 테스트 케이스
|
||
|
|
|
||
|
|
| # | 시나리오 | 입력 | 예상 결과 | 실제 결과 | 상태 |
|
||
|
|
|---|---------|------|----------|----------|------|
|
||
|
|
| 1 | 스크린 개소 검사 저장 | 모든 항목 양호 입력 | API 200, options.inspection_data 저장됨 | | ⏳ |
|
||
|
|
| 2 | 저장된 검사 데이터 로드 | 화면 재진입 | inspectionDataMap에 기존 데이터 표시 | | ⏳ |
|
||
|
|
| 3 | 이미 검사한 개소 재클릭 | 검사 완료된 item 클릭 | 기존 데이터 폼에 표시 | | ⏳ |
|
||
|
|
| 4 | 검사성적서보기 | 모든 개소 검사 완료 후 클릭 | 템플릿 레이아웃 + 전체 데이터 표시 | | ⏳ |
|
||
|
|
| 5 | 일부 개소만 검사 후 성적서 | 6개 중 3개만 검사 | 검사된 3개만 데이터, 3개는 빈 행 | | ⏳ |
|
||
|
|
| 6 | 종합 판정 자동 계산 | 1개 부적 + 나머지 적합 | 종합: 불합격, 부적합 내용 표시 | | ⏳ |
|
||
|
|
|
||
|
|
### 9.2 성공 기준
|
||
|
|
|
||
|
|
| 기준 | 달성 | 비고 |
|
||
|
|
|------|------|------|
|
||
|
|
| 개소별 검사 데이터가 서버에 저장됨 | ⏳ | 새로고침 후에도 유지 |
|
||
|
|
| 저장된 데이터가 InspectionInputModal에 자동 로드됨 | ⏳ | |
|
||
|
|
| 검사성적서보기에서 모든 개소 데이터가 합쳐져 표시됨 | ⏳ | |
|
||
|
|
| 문서 템플릿 레이아웃 적용됨 | ⏳ | 결재란, 기본정보, 섹션 구조 |
|
||
|
|
| 기존 하드코딩 성적서와 동일한 출력물 | ⏳ | 회귀 방지 |
|
||
|
|
| 자동 판정 로직 정상 동작 | ⏳ | 행별 + 종합 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 11. 자기완결성 점검 결과
|
||
|
|
|
||
|
|
### 10.1 체크리스트 검증
|
||
|
|
|
||
|
|
| # | 검증 항목 | 상태 | 비고 |
|
||
|
|
|---|----------|:----:|------|
|
||
|
|
| 1 | 작업 목적이 명확한가? | ✅ | 섹션 1.1 배경에 명시 |
|
||
|
|
| 2 | 성공 기준이 정의되어 있는가? | ✅ | 섹션 10.2 성공 기준 6개 |
|
||
|
|
| 3 | 작업 범위가 구체적인가? | ✅ | Phase 1-4, 14개 작업 항목 |
|
||
|
|
| 4 | 의존성이 명시되어 있는가? | ✅ | Phase 의존 관계 + 문서관리 시스템 80% 완료 전제 |
|
||
|
|
| 5 | 참고 파일 경로가 정확한가? | ✅ | 절대 경로 포함 핵심 파일 목록 |
|
||
|
|
| 6 | 단계별 절차가 실행 가능한가? | ✅ | 섹션 6 상세 작업 절차 |
|
||
|
|
| 7 | 검증 방법이 명시되어 있는가? | ✅ | 섹션 10.1 테스트 케이스 6개 |
|
||
|
|
| 8 | 모호한 표현이 없는가? | ✅ | API 스키마, 데이터 구조, 검사 항목 매핑, 코드 스니펫 모두 구체적 |
|
||
|
|
| 9 | 현재 코드 구조가 이해 가능한가? | ✅ | 핵심 타입/인터페이스 + 백엔드 모델/라우트 코드 포함 |
|
||
|
|
| 10 | 현재 동작 흐름이 파악 가능한가? | ✅ | 섹션 2.1 현재 흐름도 + 문제점 명시 |
|
||
|
|
|
||
|
|
### 11.2 새 세션 시뮬레이션 테스트
|
||
|
|
|
||
|
|
| 질문 | 답변 가능 | 참조 섹션 |
|
||
|
|
|------|:--------:|----------|
|
||
|
|
| Q1. 이 작업의 목적은 무엇인가? | ✅ | 1.1 배경 |
|
||
|
|
| Q2. 현재 시스템이 어떻게 동작하는가? | ✅ | 2.1 현재 동작 흐름 + 코드 스니펫 |
|
||
|
|
| Q3. 어디서부터 시작해야 하는가? | ✅ | 📍 현재 진행 상태 + 6. 상세 작업 절차 |
|
||
|
|
| Q4. 어떤 파일을 수정해야 하는가? | ✅ | 핵심 파일 목록 + Phase별 관련 파일 |
|
||
|
|
| Q5. 기존 코드의 타입/인터페이스는? | ✅ | 현재 코드 구조 (InspectionData, WorkItemData, WorkOrderItem) |
|
||
|
|
| Q6. 백엔드에 뭐가 있고 뭐가 없는가? | ✅ | 2.3 API 현황 + 백엔드 라우트/컨트롤러 구조 |
|
||
|
|
| Q7. 작업 완료 확인 방법은? | ✅ | 10.1 테스트 케이스 + 10.2 성공 기준 |
|
||
|
|
| Q8. 막혔을 때 참고 문서는? | ✅ | 9. 참고 문서 |
|
||
|
|
|
||
|
|
**결과**: 8/8 통과 → ✅ 자기완결성 확보
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 12. 세션 및 메모리 관리 정책
|
||
|
|
|
||
|
|
### 11.1 세션 시작 시
|
||
|
|
|
||
|
|
```
|
||
|
|
1. 이 문서의 📍 현재 진행 상태 확인
|
||
|
|
2. 해당 Phase 상세 절차 읽기
|
||
|
|
3. 관련 파일 읽기
|
||
|
|
4. "Phase X.X 시작할까요?" 확인
|
||
|
|
```
|
||
|
|
|
||
|
|
### 11.2 작업 중
|
||
|
|
|
||
|
|
```
|
||
|
|
- 변경 이력 섹션에 실시간 기록
|
||
|
|
- Phase/항목별 상태 업데이트 (⏳ → 🔄 → ✅)
|
||
|
|
- 컨펌 필요사항 → 컨펌 대기 목록에 추가
|
||
|
|
```
|
||
|
|
|
||
|
|
### 11.3 세션 종료 시
|
||
|
|
|
||
|
|
```
|
||
|
|
- 📍 현재 진행 상태 업데이트
|
||
|
|
- 변경 이력에 최종 업데이트 기록
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
*이 문서는 /sc:plan 스킬로 생성되었습니다. (2026-02-07)*
|