Files
sam-react-prod/claudedocs/item-master/[ANALYSIS-2025-12-06] item-data-mapping-checklist.md
byeongcheolryu ded0bc2439 fix: TypeScript 타입 오류 수정 및 설정 페이지 추가
- BOMItem Omit 타입 시그니처 통일 (useTemplateManagement, SectionsTab, ItemMasterContext)
- HeadersInit → Record<string, string> 타입 변경
- Zustand useShallow 마이그레이션 (zustand/react/shallow)
- DataTable, ListPageTemplate 제네릭 타입 제약 추가
- 설정 관리 페이지 추가 (직급, 직책, 휴가정책, 근무일정, 권한)
- HR 관리 페이지 추가 (급여, 휴가)
- 단가관리 페이지 리팩토링

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 18:07:47 +09:00

19 KiB

품목관리 데이터 누락 조사 체크리스트

품목기준관리 데이터 기반 품목관리 등록/수정 시 데이터 매핑 분석

조사 방법

  • 프론트엔드 → 백엔드: DynamicItemForm submit 데이터 분석
  • 백엔드 → 프론트엔드: API 응답 → Edit 페이지 데이터 매핑 분석
  • DB 필드: Material/Product 모델 fillable 필드 확인

1. 소모품 (SM - Supplies Material)

사용 모델: Material

Material 모델 fillable 필드

필드명 타입 필수 설명
tenant_id int Y 테넌트 ID
category_id int N 분류 ID
name string Y 품목명
item_name string N 품목명 (레거시)
specification string N 규격
material_code string Y 품목코드
material_type string Y SM/RM/CS
unit string Y 단위
is_inspection string N 검사 여부
search_tag string N 검색 태그
remarks string N 비고
attributes json N 동적 속성
options json N 옵션 배열
created_by int N 생성자
updated_by int N 수정자
is_active bool N 활성 상태

등록 시 데이터 매핑 체크리스트

프론트엔드 → 백엔드

프론트엔드 필드 백엔드 필드 변환 함수 상태 비고
- [ ] item_name / 품목명 name fieldKeyToBackendKey
- [ ] specification / 규격 specification standard_* → options + specification convertStandardFieldsToOptions()
- [ ] unit / 단위 unit fieldKeyToBackendKey
- [ ] note / 비고 remarks transformMaterialDataForSave note → remarks
- [ ] is_active / 상태 is_active boolean 변환
- [ ] code (자동생성) material_code transformMaterialDataForSave name-specification
- [ ] product_type material_type transformMaterialDataForSave
- [ ] standard_* options convertStandardFieldsToOptions 배열로 변환

백엔드 → 프론트엔드 (수정 시)

백엔드 필드 프론트엔드 필드 변환 위치 상태 비고
- [ ] name item_name mapApiResponseToFormData
- [ ] specification specification mapApiResponseToFormData
- [ ] unit unit mapApiResponseToFormData
- [ ] remarks note mapApiResponseToFormData remarks → note
- [ ] is_active is_active mapApiResponseToFormData
- [ ] material_code (참조만) - 품목코드는 수정 불가
- [ ] material_type (참조만) - 품목유형은 수정 불가
- [ ] options standard_* convertOptionsToStandardFields 배열 → 개별 필드

API 엔드포인트

  • 등록: POST /api/v1/items → ItemsService.createMaterial()
  • 조회: GET /api/v1/items/{id}?item_type=MATERIAL
  • 수정: PATCH /api/v1/products/materials/{id}

누락 가능성 분석

  • options 필드 로드 확인: Edit 시 options 배열이 standard_* 필드로 정상 변환되는지
  • specification 생성 로직: 등록 시 standard_* 값들이 specification으로 조합되는지
  • material_code 자동생성: name-specification 형식으로 생성되는지
  • is_inspection 필드: 프론트엔드에 검사여부 필드가 있는지

2. 원자재 (RM - Raw Material)

사용 모델: Material (SM과 동일)

등록/수정 데이터 매핑 (SM과 동일)

  • SM과 동일한 Material 모델 사용
  • material_type = 'RM'

원자재 특화 필드 체크리스트

프론트엔드 필드 백엔드 필드 상태 비고
- [ ] 분류 선택 (드롭다운) category_id 원자재 카테고리
- [ ] 규격 옵션들 (standard_*) options 원자재별 규격 옵션

누락 가능성 분석

  • category_id 매핑: 분류 선택이 제대로 저장되는지
  • 원자재별 옵션 구조: 품목기준관리에서 정의한 standard_1~N 필드들

3. 부자재 (CS - Consumable Supplies)

사용 모델: Material (SM, RM과 동일)

등록/수정 데이터 매핑 (SM과 동일)

  • material_type = 'CS'

부자재 특화 필드 체크리스트

프론트엔드 필드 백엔드 필드 상태 비고
- [ ] 규격 옵션들 (standard_*) options 부자재별 규격 옵션

누락 가능성 분석

  • SM/RM과 동일한 구조 사용 확인

4. 조립부품 (PT - Assembly)

사용 모델: Product

Product 모델 fillable 필드

필드명 타입 필수 설명
tenant_id int Y 테넌트 ID
code string Y 품목코드
name string Y 품목명
unit string Y 단위
category_id int N 분류 ID
product_type string Y FG/PT
attributes json N 동적 속성
description string N 설명
is_sellable bool N 판매가능
is_purchasable bool N 구매가능
is_producible bool N 생산가능
safety_stock int N 안전재고
lead_time int N 리드타임
is_variable_size bool N 가변사이즈
product_category string N 제품분류
part_type string N 부품유형 (ASSEMBLY/BENDING/PURCHASED)
bending_diagram string N 전개도 경로
bending_details json N 절곡 상세
specification_file string N 시방서 경로
certification_file string N 인정서 경로
is_active bool N 활성 상태

조립부품 특화 필드 체크리스트

프론트엔드 → 백엔드

프론트엔드 필드 백엔드 필드 변환 상태 비고
- [ ] 품목명 (드롭다운 선택) name autoAssemblyItemName "품목명 가로x세로" 형식
- [ ] 측면규격(가로) (attributes?) side_spec_width
- [ ] 측면규격(세로) (attributes?) side_spec_height
- [ ] 길이 (attributes?) assembly_length
- [ ] 규격 (자동생성) spec/description autoAssemblySpec "가로x세로x길이" 형식
- [ ] 품목코드 (자동생성) code autoGeneratedItemCode 영문약어-순번
- [ ] 단위 unit
- [ ] 비고 note/description
- [ ] 품목상태 is_active
- [ ] 전개도 이미지 bending_diagram uploadItemFile() 파일 업로드
- [ ] BOM 구성 bom[] 자재명세서

백엔드 → 프론트엔드 (수정 시)

백엔드 필드 프론트엔드 필드 상태 비고
- [ ] name item_name
- [ ] code (참조만) 품목코드
- [ ] part_type part_type ASSEMBLY
- [ ] side_spec_width 측면규격(가로) attributes에서?
- [ ] side_spec_height 측면규격(세로) attributes에서?
- [ ] assembly_length 길이 attributes에서?
- [ ] is_active is_active
- [ ] bending_diagram bending_diagram 기존 전개도 URL

누락 가능성 분석

  • 측면규격 가로/세로 필드: 백엔드에서 별도 컬럼으로 저장되는지 vs attributes JSON
  • 길이 필드: assembly_length 저장 여부
  • 전개도 이미지 로드: Edit 시 기존 이미지 표시
  • BOM 데이터 로드: component_lines 관계 로드 확인

5. 절곡부품 (PT - Bending)

사용 모델: Product (조립부품과 동일)

절곡부품 특화 필드 체크리스트

프론트엔드 → 백엔드

프론트엔드 필드 백엔드 필드 변환 상태 비고
- [ ] 품목명 (드롭다운 선택) name bendingFieldKeys.itemName
- [ ] 재질 (attributes?) bendingFieldKeys.material
- [ ] 종류 (attributes?) bendingFieldKeys.category
- [ ] 폭 합계 width_sum bendingFieldKeys.widthSum
- [ ] 모양&길이 (attributes?) bendingFieldKeys.shapeLength
- [ ] 품목코드 (자동생성) code autoBendingItemCode "품목명+종류+모양길이"
- [ ] 단위 unit
- [ ] 비고 note
- [ ] 전개도 이미지 bending_diagram uploadItemFile()
- [ ] 절곡 상세 bending_details [{angle, length, type}]

백엔드 → 프론트엔드 (수정 시)

백엔드 필드 프론트엔드 필드 상태 비고
- [ ] name item_name
- [ ] part_type part_type BENDING
- [ ] bending_diagram bending_diagram 전개도 URL
- [ ] bending_details bendingDetails 절곡 상세 배열
- [ ] width_sum widthSum
- [ ] is_active is_active

누락 가능성 분석

  • 재질/종류/모양길이 필드: 저장 위치 (별도 컬럼 vs attributes)
  • 절곡 상세 데이터: bending_details JSON 저장 및 로드
  • 전개도 파일 업로드: 파일 경로 저장 확인

6. 구매부품 (PT - Purchased)

사용 모델: Product (조립/절곡부품과 동일)

구매부품 특화 필드 체크리스트

프론트엔드 → 백엔드

프론트엔드 필드 백엔드 필드 변환 상태 비고
- [ ] 품목명 (전동개폐기 등) name purchasedFieldKeys.itemName
- [ ] 용량 (attributes?) purchasedFieldKeys.capacity
- [ ] 전원 (attributes?) purchasedFieldKeys.power
- [ ] 품목코드 (자동생성) code autoPurchasedItemCode "품목명+용량+전원"
- [ ] 단위 unit
- [ ] 비고 note

백엔드 → 프론트엔드 (수정 시)

백엔드 필드 프론트엔드 필드 상태 비고
- [ ] name item_name
- [ ] part_type part_type PURCHASED
- [ ] capacity 용량 attributes에서?
- [ ] power 전원 attributes에서?
- [ ] is_active is_active

누락 가능성 분석

  • 용량/전원 필드: 저장 위치 (별도 컬럼 vs attributes)
  • 품목코드 자동생성: "전동개폐기150KG380V" 형식 확인

7. 제품 (FG - Finished Goods)

사용 모델: Product

제품 특화 필드 체크리스트

프론트엔드 → 백엔드

프론트엔드 필드 백엔드 필드 변환 상태 비고
- [ ] 품목명 name productName 필드
- [ ] 품목코드 code = name 품목명이 품목코드
- [ ] 제품분류 product_category
- [ ] 로트약어 lot_abbreviation
- [ ] 인정번호 certification_number
- [ ] 인정유효기간 시작 certification_start_date
- [ ] 인정유효기간 종료 certification_end_date
- [ ] 시방서 파일 specification_file uploadItemFile()
- [ ] 인정서 파일 certification_file uploadItemFile()
- [ ] 단위 unit 기본값 'EA'
- [ ] BOM 구성 bom[]
- [ ] 품목상태 is_active

백엔드 → 프론트엔드 (수정 시)

백엔드 필드 프론트엔드 필드 상태 비고
- [ ] name item_name
- [ ] code (참조만)
- [ ] product_category product_category
- [ ] lot_abbreviation lot_abbreviation
- [ ] certification_number certification_number
- [ ] certification_start_date certification_start_date
- [ ] certification_end_date certification_end_date
- [ ] specification_file specification_file 기존 시방서 URL
- [ ] specification_file_name specification_file_name 파일명
- [ ] certification_file certification_file 기존 인정서 URL
- [ ] certification_file_name certification_file_name 파일명
- [ ] is_active is_active

누락 가능성 분석

  • 인정서 관련 필드: certification_* 필드들 저장 확인
  • 시방서/인정서 파일: Edit 시 기존 파일 표시 및 다운로드
  • BOM 데이터 로드: 제품의 component_lines 관계 로드

공통 이슈 체크리스트

1. 필드명 매핑 이슈

  • note vs remarks: Material은 remarks, Product는 description/note
  • is_active boolean 변환: "활성"/"비활성" vs true/false
  • field_key 형식: "{id}_{fieldName}" → 백엔드 필드명 변환

2. 동적 필드 저장 방식

  • attributes JSON: 품목기준관리에서 정의한 추가 필드들이 attributes에 저장되는지
  • options JSON: Material의 standard_* 필드들이 options 배열로 저장되는지

3. 파일 업로드

  • 품목 저장 후 파일 업로드 순서
  • Edit 시 기존 파일 표시
  • 파일 삭제 기능

4. API 엔드포인트 일관성

  • Material(SM, RM, CS):

    • 등록: POST /api/v1/items
    • 조회: GET /api/v1/items/{id}?item_type=MATERIAL
    • 수정: PATCH /api/v1/products/materials/{id} ⚠️ 경로 불일치
  • Product(FG, PT):

    • 등록: POST /api/v1/items
    • 조회: GET /api/v1/items/code/{code}?include_bom=true
    • 수정: PUT /api/v1/items/{id}

조사 진행 상황

소모품 (SM) - 진행중

  • 모델 구조 분석
  • API 엔드포인트 확인
  • 등록 데이터 흐름 테스트
  • 수정 데이터 흐름 테스트
  • 누락 필드 식별

원자재 (RM) - 대기

  • 등록/수정 테스트
  • SM과 차이점 확인

부자재 (CS) - 대기

  • 등록/수정 테스트
  • SM과 차이점 확인

조립부품 (PT-Assembly) - 대기

  • 특화 필드 저장 위치 확인
  • 등록/수정 테스트

절곡부품 (PT-Bending) - 대기

  • 특화 필드 저장 위치 확인
  • 전개도 업로드 테스트

구매부품 (PT-Purchased) - 대기

  • 특화 필드 저장 위치 확인
  • 등록/수정 테스트

제품 (FG) - 대기

  • 인정서 관련 필드 확인
  • 파일 업로드 테스트

발견된 이슈

이슈 #1: Material is_active 필드 누락

  • 품목유형: SM, RM, CS (Material 타입 전체)
  • 현상: 등록/수정 시 품목 상태(is_active) 필드가 백엔드로 전달되지 않음
  • 원인:
    1. ItemsService.createMaterial()에서 is_active 설정 O
    2. MaterialService.setMaterial()에서는 is_active 필드가 validation rules에 없음
    3. 프론트엔드 transformMaterialDataForSave()에서 is_active를 별도 처리하지 않음
  • 해결방안:
    • 백엔드: MaterialService validation rules에 'is_active' => 'nullable|boolean' 추가
    • 또는 프론트엔드에서 /api/v1/items 엔드포인트 사용 (이미 is_active 지원)
  • 우선순위: 🔴 높음

이슈 #2: Material 수정 API 경로 불일치

  • 품목유형: SM, RM, CS
  • 현상: 등록은 /api/v1/items, 수정은 /api/v1/products/materials/{id} 사용
  • 원인: 두 개의 다른 서비스 (ItemsService vs MaterialService)가 Material 처리
  • 영향:
    • ItemsService.createMaterial(): is_active, material_type 필드 처리 O
    • MaterialService.updateMaterial(): is_active 필드 validation 없음, material_type 변경 불가
  • 해결방안:
    • 통합: 수정도 /api/v1/items/{id} 사용하도록 프론트엔드 수정
    • 또는 백엔드: MaterialService.updateMaterial()에 is_active 필드 추가
  • 우선순위: 🟡 중간

이슈 #3: PT(부품) 특화 필드 저장 위치 불명확

  • 품목유형: PT (조립/절곡/구매 부품)
  • 현상: 측면규격, 용량, 전원 등 부품별 특화 필드가 어디에 저장되는지 불명확
  • 원인:
    • Product 모델에 side_spec_width, side_spec_height, assembly_length 등 컬럼 없음
    • attributes JSON에 저장되어야 하나, 프론트엔드에서 attributes 변환 로직 부재
  • 영향: 부품 수정 시 특화 필드 값이 유실될 수 있음
  • 해결방안:
    1. 백엔드: Product 모델에 부품 특화 필드 컬럼 추가 (마이그레이션)
    2. 또는: 프론트엔드에서 특화 필드를 attributes JSON으로 변환하여 저장
  • 우선순위: 🔴 높음

이슈 #4: BOM 데이터 저장 로직 누락

  • 품목유형: FG, PT (조립부품)
  • 현상: 프론트엔드에서 BOM 라인을 폼에 입력하지만 저장 시 무시됨
  • 원인:
    • ItemsService.createProduct()에서 bom 배열 처리 로직 없음
    • ProductComponent 모델에 데이터 생성하는 코드 부재
  • 영향: BOM 구성품 정보가 저장되지 않음
  • 해결방안:
    • 백엔드: ItemsService.createProduct()ProductComponent 레코드 생성 로직 추가
    • 별도 API: /api/v1/items/{id}/bom 엔드포인트로 BOM 저장
  • 우선순위: 🔴 높음

이슈 #5: 품목기준관리 동적 필드와 백엔드 필드 불일치

  • 품목유형: 전체
  • 현상: 품목기준관리에서 정의한 필드가 백엔드 모델에 대응 컬럼이 없음
  • 예시:
    • 품목기준관리: 107_재질, 108_종류, 109_폭합계
    • 백엔드 Product 모델: 해당 컬럼 없음
  • 원인: 동적 필드 구조 vs 고정 스키마 불일치
  • 해결방안:
    1. 동적 필드는 attributes JSON에 저장
    2. 프론트엔드: 품목기준관리 field_key를 attributes[field_key] 형태로 변환
    3. 백엔드: attributes 필드에서 동적 값 저장/조회 지원
  • 우선순위: 🔴 높음

이슈 #6: Material options 필드 Edit 시 로드 확인 필요

  • 품목유형: SM, RM, CS
  • 현상: 등록 시 standard_* → options 변환은 되지만, Edit 시 역변환 확인 필요
  • 확인사항:
    • mapApiResponseToFormData()에서 options → standard_* 변환 로직 있음 (line 123-129)
    • 하지만 Material API 응답에서 options가 제대로 포함되는지 확인 필요
  • 해결방안: 실제 데이터로 테스트 필요
  • 우선순위: 🟢 낮음

권장 조치사항

즉시 조치 (우선순위 높음)

  1. 이슈 #1 해결: MaterialService.setMaterial()updateMaterial()is_active validation 추가
  2. 이슈 #3 해결: PT 부품 특화 필드 저장 방식 결정
    • Option A: DB 마이그레이션으로 컬럼 추가
    • Option B: attributes JSON 활용
  3. 이슈 #4 해결: BOM 저장 API 구현

중기 조치 (우선순위 중간)

  1. 이슈 #2 해결: Material 등록/수정 API 일관성 확보
  2. 이슈 #5 해결: 동적 필드 ↔ attributes 매핑 체계 구축

테스트 필요

  1. 이슈 #6 확인: 실제 데이터로 Material Edit 플로우 테스트

다음 단계

  • 각 이슈별 수정 작업 진행
  • 실제 데이터로 등록/수정 흐름 테스트
  • 누락된 필드 추가 발견 시 문서 업데이트