Files
sam-docs/plans/integrated-phase-2.md
권혁성 666c80c350 docs: [통합계획] 제품코드 추적성 + 검사 단위 구조 통합 계획 수립
- integrated-master-plan.md: 7 Phase 통합 마스터 (의존성 맵, 진행 관리)
- integrated-phase-0-1.md: 사전 조사 + product_code 전파 수정 상세
- integrated-phase-2.md: 절곡 분석/설계 + 견적/품질 개선 상세
- integrated-phase-3.md: 절곡 검사 동적 구현 상세
- 원본 2개 문서 아카이브 전환 (통합 문서 링크 추가)
- INDEX.md 통합 문서 등록
2026-02-27 10:15:19 +09:00

10 KiB

Phase 2: 절곡 검사 분석/설계 + 견적/품질 개선

통합 계획: integrated-master-plan.md 원본:


1. Phase 2A: 절곡 검사 분석/설계

목표: 절곡 구성품(검사 항목) 정보를 API에서 제공하는 구조 설계 Phase 1과 병렬 가능 (분석 전용, 코드 변경 없음)

1.1 작업 항목

# 작업 항목 상태 비고
2A.1 절곡 제품코드별 구성품(BOM) 데이터 구조 분석 items/BOM 테이블에서 KWE01/KSS01/KSS02 확인
2A.2 마감유형(S1/S2/S3)별 차이 분석 5130 레거시 참조
2A.3 inspection-config 범용 API 설계 GET /api/v1/work-orders/{id}/inspection-config (I5 정책)
2A.4 DEFAULT_GAP_PROFILES 기준치 5130 대조 I1: Single Source of Truth 보정

1.2 구성품 데이터 소스 분석 대상

분석 대상:
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 — 현재 기준치

1.3 구성품 결정 로직 (설계안)

입력: work_order_id
  ↓
1차: 작업지시 → 공정 자동 판별 (inspection-config API)
  ↓
2차: product_code → BOM 테이블에서 하위 구성품 조회
  ↓ (BOM 미등록 시)
3차: DEFAULT_GAP_PROFILES 기본값 사용
  ↓ (템플릿 미설정 시 = 레거시)
4차: INITIAL_PRODUCTS fallback (BendingInspectionContent, KWE01 하위호환)

각 단계의 역할은 다음과 같다.

  • 1차 (공정 판별): work_order_id로부터 작업지시의 공정 타입(bending, screen, slat)을 자동 판별한다. 비절곡 공정이면 빈 items 배열을 반환하고 종료한다.
  • 2차 (BOM 조회): 해당 제품코드의 BOM에 등록된 구성품 목록을 조회한다. BOM 데이터가 있으면 이를 기준으로 검사 항목을 구성한다.
  • 3차 (기본 프로파일): BOM에 구성품이 등록되지 않은 경우, DEFAULT_GAP_PROFILES에 정의된 기본 갭 기준치를 사용한다.
  • 4차 (레거시 fallback): 템플릿 설정도 없는 경우, 기존 BendingInspectionContentINITIAL_PRODUCTS 7개 항목을 KWE01 전용 하위호환으로 사용한다.

1.4 inspection-config 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": "1", "design_value": "30" },
          { "point": "2", "design_value": "78" }
        ]
      }
    ]
  }
}

비절곡 Response (스크린/슬랫):

{
  "data": {
    "work_order_id": 456,
    "process_type": "screen",
    "product_code": "FG-KQTS01",
    "template_id": 12,
    "items": []
  }
}

응답 필드 설명:

필드 타입 설명
work_order_id integer 작업지시 ID
process_type string 공정 타입 (bending, screen, slat)
product_code string 제품코드
finish_type string|null 마감유형 (절곡 전용: S1, S2, S3)
template_id integer|null 검사 양식 ID
items array 검사 대상 구성품 목록 (비절곡 시 빈 배열)
items[].id string 구성품 식별자 (kebab-case)
items[].category string 제품 카테고리 코드
items[].product_name string 구성품 명칭
items[].product_type string 구성품 유형/규격
items[].length_design string 설계 길이
items[].width_design string 설계 폭 (N/A 가능)
items[].gap_points array 갭 측정 포인트 목록

1.5 현재 하드코딩 현황 (레거시 동결 -- C3)

BendingInspectionContent.tsxINITIAL_PRODUCTS (7개, KWE01 전용):

# 항목 ID productName productType gapPoints 수
1 guide-rail-wall 가이드레일 벽면형 5
2 guide-rail-side 가이드레일 측면형 5
3 case 케이스 500X380 4
4 bottom-finish 하단마감재 60X40 2
5 bottom-l-bar 하단L-BAR 17X60 1
6 smoke-w50 연기차단재 W50 가이드레일용 2
7 smoke-w80 연기차단재 W80 케이스용 2

Phase 2A 분석 완료 후, 이 하드코딩 항목들은 inspection-config API 응답으로 대체될 예정이다. 현재는 C3(레거시 동결) 정책에 따라 수정하지 않는다.


2. Phase 2B: 견적/수주 정합성 + 품질검사 FK

목표: quotes.product_code 활용 + inspectionswork_orders FK 연결 선행 조건: Phase 1 완료 내부 병렬성: 2B-견적과 2B-품질은 독립 경로

Phase 2B 내부 구조:

  Phase 1 완료
       |
  +----+----+
  |         |
2B-견적   2B-품질
(2B.1~3)  (2B.4~7)
  |         |
  +----+----+
       |
    Phase 2B 완료

2.1 견적 데이터 정합성 (원본 Phase 2)

# 작업 항목 상태 비고
2B.1 견적 저장 시 quotes.product_code 저장 다중 개소: 첫 번째 개소 코드 대표 저장
2B.2 견적→수주 변환 시 camelCasesnake_case 변환 확인 OrderService::createFromQuote
2B.3 기존 데이터 보정 스크립트 calculation_inputs에서 추출

다중 개소 정책: quotes.product_code에는 첫 번째 개소 코드를 대표값으로 저장한다. 전체 목록은 calculation_inputs.items[].productCode를 참조한다.

의존성 주의: orders.item_id 설정은 items 테이블에 FG 품목 등록이 필요하므로 Phase 5에서 처리한다.

데이터 보정 스크립트 상세:

// 2B.3 보정 로직 개요
// quotes 테이블에서 product_code가 null인 레코드 대상
// calculation_inputs JSON에서 items[0].productCode 추출하여 저장

$quotes = Quote::whereNull('product_code')
    ->whereNotNull('calculation_inputs')
    ->get();

foreach ($quotes as $quote) {
    $inputs = json_decode($quote->calculation_inputs, true);
    $productCode = $inputs['items'][0]['productCode'] ?? null;
    if ($productCode) {
        $quote->update(['product_code' => $productCode]);
    }
}

2.2 품질검사 연결 강화 (원본 Phase 3)

# 작업 항목 상태 비고
2B.4 inspections 테이블에 work_order_id FK 마이그레이션 nullable
2B.5 Inspection 모델에 workOrder() 관계 메서드 추가 N+1 방지
2B.6 품질검사 생성 시 work_order_id 설정 로직 InspectionService
2B.7 기존 inspections 데이터에 work_order_id 보정 lot_no 기반 역추적 (중복 사전 확인)

마이그레이션 설계 (2B.4):

Schema::table('inspections', function (Blueprint $table) {
    $table->unsignedBigInteger('work_order_id')->nullable()->after('id');
    $table->foreign('work_order_id')
          ->references('id')
          ->on('work_orders')
          ->nullOnDelete();
    $table->index('work_order_id');
});

모델 관계 (2B.5):

// Inspection.php
public function workOrder(): BelongsTo
{
    return $this->belongsTo(WorkOrder::class);
}

// WorkOrder.php
public function inspections(): HasMany
{
    return $this->hasMany(Inspection::class);
}

역추적 보정 로직 (2B.7):

inspections.lot_no → work_order_items.lot_no → work_orders.id
  |
중복 검사: 동일 lot_no에 다수 work_order 매칭 시 경고 로그
  |
MATCH: work_order_id 설정
NO_MATCH: null 유지 (수동 보정 대상)

3. 검증 결과

3.1 Phase 2A 검증

조사 항목 결과 판단
KWE01 BOM 구성품 수
KSS01 BOM 구성품 수
KSS02 BOM 구성품 수
마감유형별 차이점
DEFAULT_GAP_PROFILES 5130 대조

3.2 Phase 2B 검증

테스트 예상 결과 실제 결과 상태
견적 저장 시 quotes.product_code 첫 번째 개소 코드
다중 개소 대표 코드 첫 번째 개소
견적→수주 변환 camelCasesnake_case 정상 변환
inspections.work_order_id FK 마이그레이션 성공, nullable
기존 inspection 조회 회귀 정상
lot_no 기반 역추적 보정 정확도 MATCH 95% 이상

4. 참고 파일

4.1 Phase 2A 관련

파일 역할
react/.../documents/TemplateInspectionContent.tsx DEFAULT_GAP_PROFILES (L176-206), buildBendingProducts (L209-274)
react/.../documents/BendingInspectionContent.tsx INITIAL_PRODUCTS (L71-135, 레거시 동결)
5130/estimate/common/common_addrowJS.php 레거시 구성품 정의
5130/output/view_inspection_bending.php 절곡 중간검사 성적서

4.2 Phase 2B 관련

파일 역할
api/app/Services/Quote/QuoteService.php 견적 서비스 (product_code L324)
api/app/Services/InspectionService.php 품질검사 서비스
api/app/Models/Quality/Inspection.php 검사 모델

5. 변경 이력

날짜 항목 변경 내용
2026-02-27 문서 작성 통합 계획 Phase 2 상세 문서 작성