- BOM 항목 추가/수정/삭제 시 섹션탭 즉시 반영 - 섹션 복제 시 UI 즉시 업데이트 (null vs undefined 이슈 해결) - 항목 수정 기능 추가 (useTemplateManagement) - 실시간 동기화 문서 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
11 KiB
11 KiB
품목기준관리 API 구조 변경 대응 작업
작업 일자: 2025-11-27
1. 백엔드 API 변경 요약
1.1 핵심 구조 변경: 독립 엔티티 + 링크 테이블
Before (CASCADE FK):
item_pages
↓ page_id FK (CASCADE) - 삭제 시 연쇄 삭제
item_sections
↓ section_id FK (CASCADE) - 삭제 시 연쇄 삭제
item_fields / item_bom_items
After (독립 + 링크):
item_pages (독립)
item_sections (독립) → entity_relationships (링크 테이블)
item_fields (독립)
item_bom_items (독립)
1.2 item_master_fields 테이블 통합 → DROP
item_master_fields테이블 삭제됨item_fields테이블에 통합:section_id→ nullable (독립 필드는 NULL)category,description,is_common컬럼 추가
결과: 마스터 항목 = item_fields WHERE section_id IS NULL
1.3 entity_relationships 테이블 구조
CREATE TABLE entity_relationships (
id BIGINT PRIMARY KEY,
tenant_id BIGINT,
group_id INT DEFAULT 1, -- 1: 품목관리
parent_type ENUM('page', 'section'),
parent_id BIGINT,
child_type ENUM('section', 'field', 'bom'),
child_id BIGINT,
order_no INT DEFAULT 0,
metadata JSON,
created_at, updated_at
);
1.4 새 API 엔드포인트 (14개)
페이지-섹션 연결:
POST /pages/{pageId}/link-section- { child_id, order_no? }DELETE /pages/{pageId}/unlink-section/{sectionId}
페이지-필드 직접 연결:
POST /pages/{pageId}/link-field- { child_id, order_no? }DELETE /pages/{pageId}/unlink-field/{fieldId}
페이지 관계 조회:
GET /pages/{pageId}/relationshipsGET /pages/{pageId}/structure⭐ 전체 구조 조회
섹션-필드 연결:
POST /sections/{sectionId}/link-field- { child_id, order_no? }DELETE /sections/{sectionId}/unlink-field/{fieldId}
섹션-BOM 연결:
POST /sections/{sectionId}/link-bom- { child_id, order_no? }DELETE /sections/{sectionId}/unlink-bom/{bomId}
섹션 관계 조회:
GET /sections/{sectionId}/relationships
순서 변경:
POST /relationships/reorder{ "parent_type": "page", "parent_id": 1, "ordered_items": [ { "child_type": "section", "child_id": 1 }, { "child_type": "section", "child_id": 2 } ] }
1.5 독립 엔티티 API
섹션:
GET /sections- 독립 섹션 목록 (is_template 필터 가능)POST /sections- 독립 섹션 생성POST /sections/{id}/clone- 섹션 복제GET /sections/{id}/usage- 섹션 사용처 조회
필드:
GET /fields- 독립 필드 목록POST /fields- 독립 필드 생성POST /fields/{id}/clone- 필드 복제GET /fields/{id}/usage- 필드 사용처 조회
BOM:
GET /bom-items- 독립 BOM 목록POST /bom-items- 독립 BOM 생성
2. 프론트엔드 수정 계획
2.1 타입 정의 수정 (item-master-api.ts) ✅ 완료
제거 또는 수정:
ItemMasterField→ItemField로 통합 (section_id = null) ✅MasterFieldRequest,MasterFieldResponsedeprecated 표시 ✅
추가:
EntityRelationship타입 추가 (EntityRelationshipResponse) ✅LinkEntityRequest타입 추가 ✅ReorderRelationshipsRequest타입 추가 ✅PageStructureResponse타입 추가 ✅LinkBomRequest타입 추가 ✅
수정:
ItemFieldResponse에category,description,is_common추가 ✅IndependentFieldRequest에category,description,is_common추가 ✅InitResponse에fields필드 추가,masterFieldsdeprecated ✅
2.2 API 함수 수정 (lib/api/item-master.ts) ✅ 완료
deprecated 표시:
masterFields.list()- deprecated,fields.list()사용 권장 ✅masterFields.create()- deprecated,fields.createIndependent()사용 권장 ✅masterFields.update()- deprecated,fields.update()사용 권장 ✅masterFields.delete()- deprecated,fields.delete()사용 권장 ✅
추가 (link/unlink API):
pages.linkSection()✅ (기존)pages.unlinkSection()✅ (기존)pages.linkField()✅pages.unlinkField()✅sections.linkField()✅ (기존)sections.unlinkField()✅ (기존)sections.linkBom()✅sections.unlinkBom()✅pages.getRelationships()✅pages.getStructure()✅ (기존)sections.getRelationships()✅relationships.reorder()✅
추가 (독립 엔티티 API) - 기존 구현됨:
sections.list()✅sections.createIndependent()✅sections.clone()✅sections.getUsage()✅fields.list()✅fields.createIndependent()✅fields.clone()✅fields.getUsage()✅
2.3 Context 수정 (ItemMasterContext.tsx) ✅ 완료
상태 변경:
itemMasterFields→ deprecated 표시 (기존 유지,independentFields병행) ✅- 독립 필드 =
independentFieldsstate 이미 존재 ✅
함수 변경 (API 마이그레이션 + deprecated 표시):
addItemMasterField→fields.createIndependent()사용 ✅updateItemMasterField→fields.update()사용 ✅deleteItemMasterField→fields.delete()사용 ✅loadItemMasterFields→ deprecated 표시 추가 ✅
신규 함수 (이미 구현됨):
linkSectionToPage(pageId, sectionId)✅ (line 2225)unlinkSectionFromPage(pageId, sectionId)✅ (line 2294)linkFieldToSection(sectionId, fieldId)✅ (line 2328)unlinkFieldFromSection(sectionId, fieldId)✅ (line 2366)
2.4 UI 컴포넌트 수정
계층구조 탭 (HierarchyTab): ✅ 완료
- 섹션 추가 시 → link-section API 사용 ✅ (기존 구현)
- 섹션 제거 시 → unlink-section API 사용 ✅ (기존 구현)
- 필드 제거 시 → unlinkFieldFromSection API 사용 ✅
- confirm/toast 메시지 "연결 해제"로 변경 ✅
- ItemMasterDataManagement.tsx에서 handleUnlinkFieldWithTracking 사용 ✅
섹션 탭 (SectionsTab): ✅ 완료 (2025-11-27)
- handleDeleteTemplateField → unlinkFieldFromSection API 호출로 변경 ✅
- SectionsTab.tsx 필드 삭제 아이콘 → Unlink 아이콘 (orange) ✅
- 버튼 title "삭제" → "연결 해제" 변경 ✅
- confirm 메시지 "연결을 해제하시겠습니까?" 변경 ✅
- toast 메시지 "항목 연결이 해제되었습니다" 변경 ✅
- useTemplateManagement.ts에 linkFieldToSection, unlinkFieldFromSection import 추가 ✅
항목 탭 (MasterFieldTab → FieldTab): ✅ 완료
- 데이터 소스: Context에서
fields.*API 사용 (2025-11-27) - CRUD → 독립 필드 API 사용 (
fields.createIndependent(),fields.update(),fields.delete()) - useMasterFieldManagement.ts에 deprecated 표시 추가
- MasterFieldTab/index.tsx UI 텍스트 "항목"으로 변경
- MasterFieldDialog 제목/설명 변경
- toast 메시지 "마스터 항목" → "항목" 변경
- 다이얼로그 텍스트 변경 완료 (FieldDialog, FieldDrawer, TemplateFieldDialog, ImportFieldDialog)
속성 탭 (AttributesTab): ✅ 분석 완료 - itemMasterFields 양방향 연동 (2025-11-27)
- 데이터 소스:
itemMasterFields(Context) + 로컬 옵션 state ✅ - 양방향 연동: 항목탭 ⇄ 속성탭 (같은 itemMasterFields 참조)
- 항목 추가/수정/삭제 → 속성탭에도 반영 ✅
- 속성 옵션 변경 → 해당 필드의 dropdown options 자동 업데이트 (useAttributeManagement.ts:131-161)
ImportFieldDialog: ✅ 탭 통합 완료 (2025-11-27)
- 항목/독립필드 탭 → 단일 필드 목록으로 통합 ✅
fieldsprop 추가,independentFields/itemMasterFieldsdeprecated ✅onImport시그니처 단순화:(source?: ImportSource)→()✅handleImportField함수: source 분기 제거 →linkFieldToSection단일 호출 ✅
3. 삭제 동작 변경
3.1 기존 (CASCADE 삭제)
페이지 삭제 → 연결된 섹션도 삭제 → 연결된 필드도 삭제
3.2 변경 후 (unlink만)
페이지 삭제 → entity_relationships에서 링크만 제거
→ 섹션은 섹션 탭에 유지
→ 필드는 항목 탭에 유지
UI에서 "삭제" vs "연결 해제" 구분:
- 연결 해제: 현재 페이지/섹션에서만 제거, 원본 유지
- 실제 삭제: 엔티티 자체를 삭제 (모든 곳에서 사라짐)
4. 데이터 통일
4.1 필드 속성 공유
현재 문제:
- 마스터 항목에서
is_required설정 - 계층구조/섹션에서는 복사본이라 반영 안됨
해결:
- 이제 같은
item_fields레코드를 링크로 참조 - 한 곳에서 수정 → 모든 곳에 반영
4.2 UI 표시 통일
| 탭 | 데이터 소스 | 용도 |
|---|---|---|
| 항목 탭 | itemMasterFields (Context) |
독립 필드 CRUD |
| 속성 탭 | itemMasterFields + 로컬 옵션 state |
단위/재질/표면처리 + 필드 연동 |
| 계층구조 탭 | entity_relationships → item_fields |
페이지-섹션-필드 구조 |
| 섹션 탭 | entity_relationships → item_fields |
섹션-필드 연결 관리 |
핵심: 모든 탭이 item_fields를 공유 → 어디서 수정해도 전체 반영!
5. 작업 체크리스트
Phase 1: 타입 및 API 수정 ✅ 완료
item-master-api.ts타입 정의 수정 ✅lib/api/item-master.tsAPI 함수 추가 ✅
Phase 2: Context 수정 ✅ 완료
ItemMasterContext.tsx상태 및 함수 수정 ✅
Phase 3: UI 컴포넌트 수정 ✅ 완료
- 계층구조 탭 - 필드 삭제 → unlink 변경 ✅
- 섹션 탭 - handleDeleteTemplateField → unlinkFieldFromSection API 호출 ✅ (2025-11-27)
- 항목 탭 - 데이터 소스 변경 + UI 텍스트 변경 ✅ (다이얼로그 포함 완료)
- 속성 탭 - 동일 데이터 소스 사용 (통합됨) ✅
- ImportFieldDialog - 탭 통합 완료 (항목/독립필드 → 필드) ✅ (2025-11-27)
Phase 4: 테스트
- 페이지 삭제 시 섹션 유지 확인
- 섹션에서 필드 제거 시 항목 탭에 유지 확인
- 필드 속성 변경 시 모든 탭에 반영 확인
6. 관련 파일
프론트엔드
src/types/item-master-api.tssrc/lib/api/item-master.tssrc/contexts/ItemMasterContext.tsxsrc/components/items/ItemMasterDataManagement.tsxsrc/components/items/ItemMasterDataManagement/tabs/HierarchyTab/src/components/items/ItemMasterDataManagement/tabs/SectionsTab.tsxsrc/components/items/ItemMasterDataManagement/tabs/MasterFieldTab/src/components/items/ItemMasterDataManagement/dialogs/ImportFieldDialog.tsx
백엔드 (참조)
app/Models/ItemMaster/EntityRelationship.phpapp/Swagger/v1/EntityRelationshipApi.phproutes/api.php