품목관리 데이터 누락 조사 체크리스트
품목기준관리 데이터 기반 품목관리 등록/수정 시 데이터 매핑 분석
조사 방법
- 프론트엔드 → 백엔드: 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}
누락 가능성 분석
2. 원자재 (RM - Raw Material)
사용 모델: Material (SM과 동일)
등록/수정 데이터 매핑 (SM과 동일)
- SM과 동일한 Material 모델 사용
- material_type = 'RM'
원자재 특화 필드 체크리스트
| 프론트엔드 필드 |
백엔드 필드 |
상태 |
비고 |
| - [ ] 분류 선택 (드롭다운) |
category_id |
|
원자재 카테고리 |
| - [ ] 규격 옵션들 (standard_*) |
options |
|
원자재별 규격 옵션 |
누락 가능성 분석
3. 부자재 (CS - Consumable Supplies)
사용 모델: Material (SM, RM과 동일)
등록/수정 데이터 매핑 (SM과 동일)
부자재 특화 필드 체크리스트
| 프론트엔드 필드 |
백엔드 필드 |
상태 |
비고 |
| - [ ] 규격 옵션들 (standard_*) |
options |
|
부자재별 규격 옵션 |
누락 가능성 분석
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 |
누락 가능성 분석
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 |
|
|
누락 가능성 분석
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 |
|
|
누락 가능성 분석
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 |
|
|
누락 가능성 분석
공통 이슈 체크리스트
1. 필드명 매핑 이슈
2. 동적 필드 저장 방식
3. 파일 업로드
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) - 진행중
원자재 (RM) - 대기
부자재 (CS) - 대기
조립부품 (PT-Assembly) - 대기
절곡부품 (PT-Bending) - 대기
구매부품 (PT-Purchased) - 대기
제품 (FG) - 대기
발견된 이슈
이슈 #1: Material is_active 필드 누락
- 품목유형: SM, RM, CS (Material 타입 전체)
- 현상: 등록/수정 시 품목 상태(is_active) 필드가 백엔드로 전달되지 않음
- 원인:
ItemsService.createMaterial()에서 is_active 설정 O
MaterialService.setMaterial()에서는 is_active 필드가 validation rules에 없음
- 프론트엔드
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 변환 로직 부재
- 영향: 부품 수정 시 특화 필드 값이 유실될 수 있음
- 해결방안:
- 백엔드: Product 모델에 부품 특화 필드 컬럼 추가 (마이그레이션)
- 또는: 프론트엔드에서 특화 필드를
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 고정 스키마 불일치
- 해결방안:
- 동적 필드는
attributes JSON에 저장
- 프론트엔드: 품목기준관리 field_key를
attributes[field_key] 형태로 변환
- 백엔드:
attributes 필드에서 동적 값 저장/조회 지원
- 우선순위: 🔴 높음
이슈 #6: Material options 필드 Edit 시 로드 확인 필요
- 품목유형: SM, RM, CS
- 현상: 등록 시 standard_* → options 변환은 되지만, Edit 시 역변환 확인 필요
- 확인사항:
mapApiResponseToFormData()에서 options → standard_* 변환 로직 있음 (line 123-129)
- 하지만 Material API 응답에서 options가 제대로 포함되는지 확인 필요
- 해결방안: 실제 데이터로 테스트 필요
- 우선순위: 🟢 낮음
권장 조치사항
즉시 조치 (우선순위 높음)
- 이슈 #1 해결:
MaterialService.setMaterial()과 updateMaterial()에 is_active validation 추가
- 이슈 #3 해결: PT 부품 특화 필드 저장 방식 결정
- Option A: DB 마이그레이션으로 컬럼 추가
- Option B: attributes JSON 활용
- 이슈 #4 해결: BOM 저장 API 구현
중기 조치 (우선순위 중간)
- 이슈 #2 해결: Material 등록/수정 API 일관성 확보
- 이슈 #5 해결: 동적 필드 ↔ attributes 매핑 체계 구축
테스트 필요
- 이슈 #6 확인: 실제 데이터로 Material Edit 플로우 테스트
다음 단계