From e2172663766ec8faa53023b6ac4a465c1401bb50 Mon Sep 17 00:00:00 2001 From: kent Date: Sun, 21 Dec 2025 13:49:28 +0900 Subject: [PATCH] =?UTF-8?q?docs:=205130=20=E2=86=92=20SAM=20=ED=92=88?= =?UTF-8?q?=EB=AA=A9=20=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EB=AC=B8=EC=84=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MASTER_PLAN.md: 마이그레이션 전체 계획 - PROGRESS.md: 진행 상황 및 최종 결과 - phase-1: 5130 소스 스키마 분석 - phase-2: SAM 타겟 스키마 분석 - phase-3: 필드 매핑 설계 마이그레이션 결과: - 총 425건 품목 이관 완료 (models 18, parts 36, parts_sub 117, BDmodels 59, BOM 195) - tenant_id: 287 (경동기업) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- projects/5130-migration/MASTER_PLAN.md | 228 ++++++++++++++++ projects/5130-migration/PROGRESS.md | 207 +++++++++++++++ .../5130-item-schema.md | 186 +++++++++++++ .../sam-item-schema.md | 249 ++++++++++++++++++ .../phase-3-mapping/field-mapping.md | 203 ++++++++++++++ 5 files changed, 1073 insertions(+) create mode 100644 projects/5130-migration/MASTER_PLAN.md create mode 100644 projects/5130-migration/PROGRESS.md create mode 100644 projects/5130-migration/phase-1-source-analysis/5130-item-schema.md create mode 100644 projects/5130-migration/phase-2-target-analysis/sam-item-schema.md create mode 100644 projects/5130-migration/phase-3-mapping/field-mapping.md diff --git a/projects/5130-migration/MASTER_PLAN.md b/projects/5130-migration/MASTER_PLAN.md new file mode 100644 index 0000000..5988178 --- /dev/null +++ b/projects/5130-migration/MASTER_PLAN.md @@ -0,0 +1,228 @@ +# 5130 → SAM 품목 마이그레이션 마스터 플랜 + +> **프로젝트**: 5130 품목(부품, 자재, BOM) 데이터를 SAM API/MNG DB로 이전 +> **시작일**: 2025-12-21 +> **목표**: 5130의 item 관련 데이터를 SAM 구조에 맞게 마이그레이션 + +--- + +## 1. 프로젝트 개요 + +### 1.1 배경 +- 5130(경동기업 레거시)과 SAM(신규 ERP)의 DB 구조가 상이 +- 수작업 데이터 입력은 불가능한 데이터 볼륨 +- 구조 분석 → 매핑 → 마이그레이션 전략 필요 + +### 1.2 핵심 원칙 +| 원칙 | 설명 | +|------|------| +| **분석 우선** | 양쪽 구조를 완벽히 파악 후 작업 | +| **문서화 필수** | 모든 매핑/변환 규칙 문서화 | +| **반복 검증** | 테스트 마이그레이션 → 수정 → 재시도 | +| **롤백 가능** | 실패 시 복구 가능한 전략 | + +### 1.3 대상 테이블 (5130) +| 테이블 | 설명 | 우선순위 | +|--------|------|----------| +| `items` | 품목 기본 정보 | 🔴 필수 | +| `item_sections` | 품목 섹션 | 🔴 필수 | +| `item_pages` | 품목 페이지 | 🟡 중요 | +| `item_id_mappings` | ID 매핑 관계 | 🟡 중요 | +| `item_fields` | 필드 정의 | 🔴 필수 | +| `item_details` | 품목 상세 데이터 | 🔴 필수 | +| `item_bom_items` | BOM 구성 | 🔴 필수 | +| `entity_relationships` | 엔티티 관계 | 🟡 중요 | + +--- + +## 2. 작업 Phase 정의 + +### Phase 1: 소스 분석 (5130) 🔵 진행중 +**목표**: 5130 DB 구조 완벽 파악 + +체크리스트: +- [x] 5130/docs 문서 확인 +- [ ] Item 관련 테이블 스키마 조회 (DB 직접) +- [ ] 테이블 간 관계도 작성 +- [ ] 데이터 샘플 확인 +- [ ] 데이터 볼륨 파악 + +**산출물**: `phase-1-source-analysis/` +- `5130-item-schema.md` - 테이블 스키마 +- `5130-item-relations.md` - 테이블 관계도 +- `5130-data-samples.md` - 데이터 샘플 + +### Phase 2: 타겟 분석 (SAM) ⚪ 대기 +**목표**: SAM API/MNG DB 구조 파악 + +체크리스트: +- [ ] api/docs 문서 확인 +- [ ] SAM items 테이블 스키마 확인 +- [ ] API 엔드포인트 구조 확인 +- [ ] Multi-tenant 구조 파악 + +**산출물**: `phase-2-target-analysis/` +- `sam-item-schema.md` +- `sam-api-endpoints.md` + +### Phase 3: 매핑 설계 ⚪ 대기 +**목표**: 5130 → SAM 변환 규칙 정의 + +체크리스트: +- [ ] 필드 매핑 테이블 작성 +- [ ] 타입 변환 규칙 정의 +- [ ] 관계 매핑 정의 +- [ ] 누락/추가 필드 식별 +- [ ] 데이터 변환 함수 설계 + +**산출물**: `phase-3-mapping/` +- `field-mapping.md` - 필드 매핑 테이블 +- `transform-rules.md` - 변환 규칙 +- `gap-analysis.md` - Gap 분석 + +### Phase 4: 마이그레이션 개발 ⚪ 대기 +**목표**: 마이그레이션 스크립트 개발 + +체크리스트: +- [ ] 마이그레이션 스크립트 설계 +- [ ] 순서 결정 (의존성 기반) +- [ ] 검증 쿼리 작성 +- [ ] 롤백 스크립트 작성 + +**산출물**: `phase-4-migration/` +- `migration-order.md` +- `scripts/` (마이그레이션 스크립트) +- `validation/` (검증 쿼리) + +### Phase 5: 실행 및 검증 ⚪ 대기 +**목표**: 실제 마이그레이션 및 검증 + +체크리스트: +- [ ] 테스트 환경 마이그레이션 +- [ ] 데이터 정합성 검증 +- [ ] 오류 수정 및 재시도 +- [ ] 최종 마이그레이션 +- [ ] 완료 리포트 작성 + +**산출물**: `FINAL_REPORT.md` + +--- + +## 3. 참조 정보 + +### 3.1 5130 시스템 +```yaml +DB명: chandj +엔진: MySQL 8.0 +PHP: 7.3 +도메인: 5130.co.kr, 5130.sam.kr (개발) +회사: 경동기업, 주일철강 +``` + +### 3.2 SAM 시스템 +```yaml +Framework: Laravel 12 +PHP: 8.4+ +Multi-tenant: tenant_id 기반 +DB: items 테이블 (products + materials 통합 완료) +``` + +### 3.3 주요 문서 +- 5130: `5130/docs/DATABASE.md`, `MODULES.md`, `README.md` +- SAM: `api/docs/`, `docs/guides/PROJECT_DEVELOPMENT_POLICY.md` +- 워크플로우: `docs/guides/common-workflow-framework.md` + +--- + +## 4. 문서 구조 + +``` +docs/projects/5130-migration/ +├── MASTER_PLAN.md # 이 문서 +├── PROGRESS.md # 진행 상황 추적 +│ +├── phase-1-source-analysis/ # 🔵 진행중 +│ ├── README.md +│ ├── 5130-item-schema.md +│ ├── 5130-item-relations.md +│ └── 5130-data-samples.md +│ +├── phase-2-target-analysis/ # ⚪ 대기 +│ ├── README.md +│ ├── sam-item-schema.md +│ └── sam-api-endpoints.md +│ +├── phase-3-mapping/ # ⚪ 대기 +│ ├── README.md +│ ├── field-mapping.md +│ ├── transform-rules.md +│ └── gap-analysis.md +│ +├── phase-4-migration/ # ⚪ 대기 +│ ├── README.md +│ ├── migration-order.md +│ ├── scripts/ +│ └── validation/ +│ +└── FINAL_REPORT.md +``` + +--- + +## 5. 세션 영속성 + +### 5.1 Serena 메모리 +``` +5130-migration-state → 현재 phase, task, 다음 액션 +5130-migration-context → 분석 결과, 결정사항, 참조 +``` + +### 5.2 세션 복구 +1. `serena.list_memories()` → 상태 확인 +2. `PROGRESS.md` → 상세 진행상황 +3. "다음 액션"부터 재개 + +### 5.3 업데이트 시점 +| 시점 | 행동 | +|------|------| +| 세션 시작 | `read_memory(state)` → 이어서 진행 | +| Phase 완료 | `write_memory(state)` + PROGRESS.md | +| 중요 발견 | `write_memory(context)` | +| 세션 종료 | 양쪽 최종 저장 | + +--- + +## 6. 작업 프로세스 + +### 6.1 기본 원칙 (common-workflow-framework 참조) +- **분석 작업**: 분석 → 문서화 → 확인 +- **마이그레이션**: 설계 → 개발 → 테스트 → 수정 (반복) + +### 6.2 단계별 프로세스 +| Phase | 유형 | 프로세스 | +|-------|------|----------| +| 1-2 | 분석 | 조사 → 문서화 → 검토 | +| 3 | 설계 | 매핑 → 규칙정의 → 검토 | +| 4 | 개발 | 스크립트 → 테스트 → 수정 | +| 5 | 실행 | 마이그레이션 → 검증 → 수정 (반복) | + +--- + +## 7. 현재 상태 + +### 7.1 Phase 1 진행 현황 +- ✅ 5130/docs 문서 확인 완료 +- ⚠️ Item 테이블 스키마가 문서에 없음 → DB 직접 조회 필요 +- ⏳ 다음 액션: 5130 DB에서 Item 테이블 스키마 조회 + +### 7.2 발견 사항 +- 5130/docs에는 `output`, `estimate`, `instock`, `eworks` 등 업무 테이블만 문서화 +- Item 관련 8개 테이블은 문서 미작성 → 실제 DB에서 직접 분석 필요 + +--- + +## 변경 이력 + +| 날짜 | 변경 내용 | 작성자 | +|------|----------|--------| +| 2025-12-21 | 초기 마스터 플랜 작성 | Claude | \ No newline at end of file diff --git a/projects/5130-migration/PROGRESS.md b/projects/5130-migration/PROGRESS.md new file mode 100644 index 0000000..718d62b --- /dev/null +++ b/projects/5130-migration/PROGRESS.md @@ -0,0 +1,207 @@ +# 5130 → SAM 마이그레이션 진행 상황 + +> 마지막 업데이트: 2025-12-21 +> 현재 Phase: **Phase 5 완료** + +--- + +## 전체 진행률 + +| Phase | 상태 | 진행률 | +|-------|------|--------| +| Phase 1: 소스 분석 (5130) | ✅ 완료 | 100% | +| Phase 2: 타겟 분석 (SAM) | ✅ 완료 | 100% | +| Phase 3: 매핑 설계 | ✅ 완료 | 100% | +| Phase 4: 마이그레이션 개발 | ✅ 완료 | 100% | +| Phase 5: 실행 및 검증 | ✅ 완료 | 100% | + +--- + +## 핵심 설정 + +| 항목 | 값 | +|------|-----| +| **tenant_id** | 287 (경동기업) | +| **제외** | 주일기업 (별도 테넌트로 추후 진행) | + +--- + +## Phase 1: 소스 분석 (5130) ✅ 완료 + +### 핵심 발견 사항 + +| 테이블 | 레코드 | 역할 | +|--------|--------|------| +| models | 18 | 완제품 (KSS01, KSE01) | +| parts | 36 | 부품 | +| parts_sub | 117 | 원자재 | +| BDmodels | 59 | 부품 (savejson에 BOM 포함) | + +**산출물:** `phase-1-source-analysis/5130-item-schema.md` + +--- + +## Phase 2: 타겟 분석 (SAM) ✅ 완료 + +### 핵심 발견 사항 + +- `items` 통합 테이블 (item_type으로 구분) +- `item_id_mappings` 레거시 ID 추적용 +- `entity_relationships` 관계 정의 + +**산출물:** `phase-2-target-analysis/sam-item-schema.md` + +--- + +## Phase 3: 매핑 설계 ✅ 완료 + +### 체크리스트 +- [x] 상세 필드 매핑 테이블 작성 +- [x] 타입 변환 규칙 정의 +- [x] tenant_id 할당 전략 (287 - 경동기업) +- [x] 코드 생성 규칙 정의 +- [x] 관계 매핑 설계 + +### 테이블 매핑 요약 + +| 5130 | → | SAM items | item_type | +|------|---|-----------|-----------| +| models (18) | → | items | FG (완제품) | +| parts (36) | → | items | PT (부품) | +| parts_sub (117) | → | items | RM (원자재) | +| BDmodels (59) | → | items | PT (부품) | +| BDmodels.savejson (195) | → | items | RM (원자재) | + +### 관계 매핑 + +| 5130 관계 | → | SAM | +|-----------|---|-----| +| parts.model_id → models | → | entity_relationships | +| parts_sub.part_id → parts | → | entity_relationships | +| BDmodels → savejson items | → | entity_relationships | + +**산출물:** `phase-3-mapping/field-mapping.md` + +--- + +## Phase 4: 마이그레이션 개발 ✅ 완료 + +### 체크리스트 +- [x] 마이그레이션 스크립트 설계 +- [x] 마이그레이션 순서 확정 +- [x] Laravel Command 작성 (`php artisan migrate:5130-items`) +- [x] 검증 쿼리 작성 +- [x] 롤백 스크립트 작성 + +### 마이그레이션 순서 (실행 완료) + +1. ✅ models → items (FG) +2. ✅ parts → items (PT) +3. ✅ parts_sub → items (RM) +4. ✅ BDmodels → items (PT) +5. ✅ BDmodels.savejson → items (RM) + entity_relationships +6. ✅ models↔parts 관계 → entity_relationships +7. ✅ parts↔parts_sub 관계 → entity_relationships +8. ✅ item_id_mappings 기록 + +**산출물:** `api/app/Console/Commands/Migrate5130Items.php` + +--- + +## Phase 5: 실행 및 검증 ✅ 완료 + +### 체크리스트 +- [x] 테스트 환경 마이그레이션 +- [x] 데이터 정합성 검증 +- [x] 오류 수정 및 재시도 +- [x] 최종 마이그레이션 +- [x] 완료 리포트 작성 + +### 최종 마이그레이션 결과 + +#### items 테이블 (tenant_id=287) + +| item_type | 건수 | 설명 | +|-----------|------|------| +| CS | 5 | 기존 데이터 | +| FG | 20 | 완제품 (models 18 + 기존 2) | +| PT | 100 | 부품 (parts 36 + BDmodels 59 + 기존 5) | +| RM | 314 | 원자재 (parts_sub 117 + BDmodels_bom 195 + 기존 2) | +| SM | 2 | 기존 데이터 | +| **Total** | **441** | | + +#### 5130 출처 items 상세 + +| source_table | 건수 | +|--------------|------| +| models | 18 | +| parts | 36 | +| parts_sub | 117 | +| BDmodels | 59 | +| BDmodels_bom | 195 | +| **Total** | **425** | + +#### item_id_mappings + +| source_table | 건수 | +|--------------|------| +| models | 18 | +| parts | 36 | +| parts_sub | 117 | +| BDmodels | 59 | +| materials | 354 (기존) | +| products | 6 (기존) | +| **Total** | **590** | + +#### entity_relationships (tenant_id=287) + +| 관계 유형 | 건수 | +|-----------|------| +| models ↔ parts | 36 | +| parts ↔ parts_sub | 117 | +| BDmodels ↔ BDmodels_bom | 195 | +| 기타 | 91 | +| **Total** | **439** | + +--- + +## 명령어 레퍼런스 + +```bash +# 전체 마이그레이션 (dry-run) +php artisan migrate:5130-items --dry-run + +# 전체 마이그레이션 (실제 실행) +php artisan migrate:5130-items --tenant_id=287 + +# 특정 단계만 실행 +php artisan migrate:5130-items --step=models +php artisan migrate:5130-items --step=parts +php artisan migrate:5130-items --step=parts_sub +php artisan migrate:5130-items --step=bdmodels +php artisan migrate:5130-items --step=relations + +# 롤백 +php artisan migrate:5130-items --rollback +``` + +--- + +## 작업 로그 + +| 날짜 | 작업 내용 | 결과 | +|------|----------|------| +| 2025-12-21 | 마스터 플랜 문서 작성 | ✅ 완료 | +| 2025-12-21 | Phase 1: 5130 DB 스키마 분석 | ✅ 완료 | +| 2025-12-21 | Phase 2: SAM DB 스키마 분석 | ✅ 완료 | +| 2025-12-21 | Phase 3: 필드 매핑 설계 (tenant_id=287) | ✅ 완료 | +| 2025-12-21 | Phase 4: Migrate5130Items Command 개발 | ✅ 완료 | +| 2025-12-21 | Phase 5: 마이그레이션 실행 및 검증 | ✅ 완료 | + +--- + +## 다음 단계 (선택적) + +1. **주일기업 마이그레이션**: 별도 테넌트로 동일 프로세스 적용 +2. **데이터 검증 UI**: SAM MNG에서 마이그레이션된 품목 조회/수정 기능 +3. **BOM 관계 활용**: 마이그레이션된 entity_relationships를 활용한 BOM 조회 API diff --git a/projects/5130-migration/phase-1-source-analysis/5130-item-schema.md b/projects/5130-migration/phase-1-source-analysis/5130-item-schema.md new file mode 100644 index 0000000..03216ab --- /dev/null +++ b/projects/5130-migration/phase-1-source-analysis/5130-item-schema.md @@ -0,0 +1,186 @@ +# 5130 품목 테이블 스키마 분석 + +> 분석일: 2025-12-21 +> DB: chandj (MySQL 8.0) + +--- + +## 1. 테이블 구조 개요 + +### 1.1 품목 관련 테이블 +| 테이블 | 레코드 수 | 설명 | +|--------|----------|------| +| `models` | 18 | 제품 모델 (KSS01, KSE01 등) | +| `parts` | 37 | 모델별 부품 | +| `parts_sub` | 134 | 부품별 세부 자재 | +| `item_list` | 9 | 품목 목록 (별도 용도) | + +### 1.2 계층 구조 +``` +models (제품 모델) + └─ parts (부품) - model_id 참조 + └─ parts_sub (세부 자재) - part_id 참조 +``` + +--- + +## 2. 테이블 상세 스키마 + +### 2.1 models (제품 모델) + +| 필드 | 타입 | NULL | 키 | 설명 | +|------|------|------|-----|------| +| model_id | int | NO | PRI | 모델 ID | +| model_name | varchar(255) | NO | | 모델명 (KSS01, KSE01 등) | +| major_category | enum('스크린','스라트') | NO | | 대분류 | +| finishing_type | enum('SUS마감','EGI마감') | NO | | 마감 유형 | +| description | text | YES | | 설명 | +| guiderail_type | varchar(20) | YES | | 가이드레일 유형 | +| is_deleted | tinyint(1) | NO | | 삭제 여부 | +| update_log | text | YES | | 변경 이력 | +| created_at | datetime | YES | | 생성일 | +| updated_at | datetime | YES | | 수정일 | + +**샘플 데이터:** +``` +model_id=12, model_name='KSS01', major_category='스크린', finishing_type='SUS마감' +model_id=14, model_name='KSE01', major_category='스크린', finishing_type='SUS마감' +``` + +### 2.2 parts (부품) + +| 필드 | 타입 | NULL | 키 | 설명 | +|------|------|------|-----|------| +| part_id | int | NO | PRI | 부품 ID | +| model_id | int | NO | MUL | 모델 ID (FK → models) | +| part_name | varchar(30) | NO | | 부품명 | +| spec | varchar(50) | YES | | 규격 (120*70 등) | +| unit | varchar(15) | YES | | 단위 (SET 등) | +| quantity | int | NO | | 수량 | +| unitprice | varchar(15) | YES | | 단가 | +| memo | text | YES | | 메모 | +| img_url | text | YES | | 이미지 URL | +| is_deleted | tinyint(1) | YES | | 삭제 여부 | +| created_at | datetime | YES | | 생성일 | +| updated_at | datetime | YES | | 수정일 | + +**샘플 데이터:** +``` +part_id=49, model_id=12, part_name='상부브라켓', spec='120*70', unit='SET', quantity=1 +part_id=50, model_id=12, part_name='하부브라켓', spec='60*40', unit='SET', quantity=2 +``` + +### 2.3 parts_sub (세부 자재) + +| 필드 | 타입 | NULL | 키 | 설명 | +|------|------|------|-----|------| +| subpart_id | int | NO | PRI | 세부 자재 ID | +| part_id | int | NO | MUL | 부품 ID (FK → parts) | +| subpart_name | varchar(255) | NO | | 자재명 | +| quantity | int | NO | | 수량 | +| material | varchar(255) | YES | | 재질 (SUS 1.2T 등) | +| bendSum | varchar(15) | YES | | 벤딩 합계 | +| plateSum | varchar(15) | YES | | 판재 합계 | +| finalSum | varchar(15) | YES | | 최종 합계 | +| unitPrice | varchar(15) | YES | | 단가 | +| computedPrice | varchar(15) | YES | | 계산 단가 | +| lineTotal | varchar(15) | YES | | 라인 합계 | +| image_url | varchar(255) | YES | | 이미지 URL | +| is_deleted | tinyint(1) | YES | | 삭제 여부 | +| created_at | datetime | YES | | 생성일 | +| updated_at | datetime | YES | | 수정일 | + +**샘플 데이터:** +``` +subpart_id=64, part_id=49, subpart_name='1차(전면)', quantity=1, material='SUS 1.2T' +subpart_id=65, part_id=49, subpart_name='2차(후면)', quantity=2, material='EGI 1.55T' +``` + +### 2.4 item_list (품목 목록) + +| 필드 | 타입 | NULL | 키 | 설명 | +|------|------|------|-----|------| +| num | int | NO | PRI | 번호 | +| item_name | varchar(100) | NO | | 품목명 | +| col13 | decimal(10,2) | YES | | 가격 | +| col60~col80 | varchar(50) | YES | | 추가 속성들 | + +> ⚠️ 컬럼명이 col60~col80으로 되어 있어 의미 파악 필요 + +--- + +## 3. 관계도 + +``` +┌─────────────────┐ +│ models │ +│ (18 레코드) │ +│ │ +│ model_id (PK) │ +│ model_name │ +│ major_category │ +│ finishing_type │ +└────────┬────────┘ + │ 1:N + ▼ +┌─────────────────┐ +│ parts │ +│ (37 레코드) │ +│ │ +│ part_id (PK) │ +│ model_id (FK) ──┤ +│ part_name │ +│ spec │ +└────────┬────────┘ + │ 1:N + ▼ +┌─────────────────┐ +│ parts_sub │ +│ (134 레코드) │ +│ │ +│ subpart_id (PK) │ +│ part_id (FK) ───┤ +│ subpart_name │ +│ material │ +└─────────────────┘ +``` + +--- + +## 4. 데이터 특성 + +### 4.1 major_category (대분류) +- `스크린` (Screen) +- `스라트` (Slat) + +### 4.2 finishing_type (마감 유형) +- `SUS마감` (스테인리스) +- `EGI마감` (아연도금) + +### 4.3 material (재질) - parts_sub +- `SUS 1.2T`, `SUS 1.5T` (스테인리스) +- `EGI 1.55T` (아연도금) + +--- + +## 5. 마이그레이션 고려사항 + +### 5.1 구조적 차이 +| 5130 | SAM | 비고 | +|------|-----|------| +| 3단계 계층 (models→parts→parts_sub) | items + item_bom_items | 구조 변환 필요 | +| 단순 FK 관계 | entity_relationships 사용 | 관계 정의 방식 다름 | +| 고정 컬럼 | JSON attributes | 유연한 속성 저장 | + +### 5.2 매핑 방향 +1. **models** → `items` (item_type='FG', 완제품) +2. **parts** → `items` (item_type='PT', 부품) +3. **parts_sub** → `items` (item_type='RM', 원자재) +4. **parts → models 관계** → `item_bom_items` 또는 `entity_relationships` +5. **parts_sub → parts 관계** → `item_bom_items` 또는 `entity_relationships` + +### 5.3 데이터 변환 필요 항목 +- `major_category` → `attributes.category` 또는 별도 분류 +- `finishing_type` → `attributes.finishing_type` +- `material` → `attributes.material` +- 가격 필드들 (varchar) → decimal 변환 \ No newline at end of file diff --git a/projects/5130-migration/phase-2-target-analysis/sam-item-schema.md b/projects/5130-migration/phase-2-target-analysis/sam-item-schema.md new file mode 100644 index 0000000..bfc45f3 --- /dev/null +++ b/projects/5130-migration/phase-2-target-analysis/sam-item-schema.md @@ -0,0 +1,249 @@ +# SAM 품목 테이블 스키마 분석 + +> 분석일: 2025-12-21 +> DB: samdb (MySQL 8.0) + +--- + +## 1. 테이블 구조 개요 + +### 1.1 품목 관련 테이블 +| 테이블 | 설명 | +|--------|------| +| `items` | 품목 기본 정보 (통합 테이블) | +| `item_details` | 품목 상세 정보 | +| `item_sections` | 섹션 정의 (UI 그룹핑) | +| `item_fields` | 필드 정의 (동적 속성) | +| `item_pages` | 페이지 정의 (품목 유형별) | +| `item_bom_items` | BOM 구성 품목 | +| `item_id_mappings` | 레거시 ID 매핑 | +| `entity_relationships` | 엔티티 간 관계 | + +### 1.2 Multi-tenant 구조 +모든 테이블에 `tenant_id` 필드로 테넌트 분리 + +--- + +## 2. 테이블 상세 스키마 + +### 2.1 items (품목 기본 정보) + +| 필드 | 타입 | NULL | 키 | 설명 | +|------|------|------|-----|------| +| id | bigint unsigned | NO | PRI | 품목 ID | +| tenant_id | bigint unsigned | NO | MUL | 테넌트 ID | +| item_type | varchar(15) | NO | | 품목 유형 (FG/PT/SM/RM/CS) | +| code | varchar(100) | NO | | 품목 코드 | +| name | varchar(255) | NO | | 품목명 | +| unit | varchar(20) | YES | | 단위 | +| category_id | bigint unsigned | YES | | 카테고리 ID | +| bom | json | YES | | BOM 정보 (JSON) | +| attributes | json | YES | | 동적 속성 (JSON) | +| attributes_archive | json | YES | | 속성 이력 | +| options | json | YES | | 옵션 | +| description | text | YES | | 설명 | +| is_active | tinyint(1) | NO | | 활성 여부 | +| created_by | bigint unsigned | YES | | 생성자 | +| updated_by | bigint unsigned | YES | | 수정자 | +| deleted_by | bigint unsigned | YES | | 삭제자 | +| created_at | timestamp | YES | | 생성일 | +| updated_at | timestamp | YES | | 수정일 | +| deleted_at | timestamp | YES | | 삭제일 (Soft Delete) | + +**item_type 값:** +- `FG`: Finished Goods (완제품) +- `PT`: Parts (부품) +- `SM`: Semi-finished (반제품) +- `RM`: Raw Materials (원자재) +- `CS`: Consumables (소모품) + +### 2.2 item_details (품목 상세) + +| 필드 | 타입 | NULL | 설명 | +|------|------|------|------| +| id | bigint unsigned | NO | ID | +| item_id | bigint unsigned | NO | 품목 ID (FK) | +| is_sellable | tinyint(1) | NO | 판매 가능 | +| is_purchasable | tinyint(1) | NO | 구매 가능 | +| is_producible | tinyint(1) | NO | 생산 가능 | +| safety_stock | int | YES | 안전 재고 | +| lead_time | int | YES | 리드 타임 | +| is_variable_size | tinyint(1) | NO | 가변 사이즈 | +| product_category | varchar(50) | YES | 제품 분류 | +| part_type | varchar(50) | YES | 부품 유형 | +| bending_diagram | varchar(255) | YES | 벤딩 도면 | +| bending_details | json | YES | 벤딩 상세 | +| specification_file | varchar(255) | YES | 규격서 파일 | +| certification_file | varchar(255) | YES | 인증서 파일 | +| certification_number | varchar(255) | YES | 인증 번호 | +| certification_start_date | date | YES | 인증 시작일 | +| certification_end_date | date | YES | 인증 종료일 | +| is_inspection | varchar(1) | NO | 검사 대상 여부 | +| item_name | varchar(255) | YES | 품목명 (검색용) | +| specification | varchar(255) | YES | 규격 | +| search_tag | text | YES | 검색 태그 | +| remarks | text | YES | 비고 | + +### 2.3 item_bom_items (BOM 구성) + +| 필드 | 타입 | NULL | 설명 | +|------|------|------|------| +| id | bigint unsigned | NO | ID | +| tenant_id | bigint unsigned | NO | 테넌트 ID | +| group_id | int unsigned | NO | 그룹 ID | +| item_code | varchar(100) | YES | 품목 코드 | +| item_name | varchar(255) | NO | 품목명 | +| quantity | decimal(15,4) | NO | 수량 | +| unit | varchar(50) | YES | 단위 | +| unit_price | decimal(15,2) | YES | 단가 | +| total_price | decimal(15,2) | YES | 합계 | +| spec | text | YES | 규격 | +| note | text | YES | 비고 | + +### 2.4 item_sections (섹션 정의) + +| 필드 | 타입 | NULL | 설명 | +|------|------|------|------| +| id | bigint unsigned | NO | ID | +| tenant_id | bigint unsigned | NO | 테넌트 ID | +| group_id | int unsigned | NO | 그룹 ID | +| title | varchar(255) | NO | 섹션 제목 | +| type | enum('fields','bom') | NO | 섹션 유형 | +| order_no | int | NO | 정렬 순서 | +| is_template | tinyint(1) | NO | 템플릿 여부 | +| is_default | tinyint(1) | NO | 기본 여부 | +| description | text | YES | 설명 | + +### 2.5 item_fields (필드 정의) + +| 필드 | 타입 | NULL | 설명 | +|------|------|------|------| +| id | bigint unsigned | NO | ID | +| tenant_id | bigint unsigned | NO | 테넌트 ID | +| group_id | int unsigned | NO | 그룹 ID | +| field_name | varchar(255) | NO | 필드명 | +| field_key | varchar(100) | YES | 필드 키 | +| field_type | enum(...) | NO | 필드 유형 | +| order_no | int | NO | 정렬 순서 | +| is_required | tinyint(1) | NO | 필수 여부 | +| default_value | text | YES | 기본값 | +| validation_rules | json | YES | 검증 규칙 | +| options | json | YES | 선택 옵션 | +| storage_type | enum('column','json') | NO | 저장 방식 | +| json_path | varchar(200) | YES | JSON 경로 | +| is_common | tinyint(1) | NO | 공통 필드 여부 | +| is_active | tinyint(1) | NO | 활성 여부 | + +**field_type 값:** +- `textbox`, `number`, `dropdown`, `checkbox`, `date`, `textarea` + +### 2.6 item_pages (페이지 정의) + +| 필드 | 타입 | NULL | 설명 | +|------|------|------|------| +| id | bigint unsigned | NO | ID | +| tenant_id | bigint unsigned | NO | 테넌트 ID | +| group_id | int unsigned | NO | 그룹 ID | +| page_name | varchar(255) | NO | 페이지명 | +| item_type | enum('FG','PT','SM','RM','CS') | NO | 품목 유형 | +| source_table | varchar(100) | YES | 소스 테이블 | +| absolute_path | varchar(500) | YES | 절대 경로 | +| is_active | tinyint(1) | NO | 활성 여부 | + +### 2.7 item_id_mappings (레거시 매핑) + +| 필드 | 타입 | NULL | 설명 | +|------|------|------|------| +| id | bigint unsigned | NO | ID | +| source_table | varchar(20) | NO | 소스 테이블 | +| source_id | bigint unsigned | NO | 소스 ID | +| item_id | bigint unsigned | NO | SAM 품목 ID | + +> ⭐ **마이그레이션 추적용 테이블** - 5130 원본 ID와 SAM ID 매핑 + +### 2.8 entity_relationships (엔티티 관계) + +| 필드 | 타입 | NULL | 설명 | +|------|------|------|------| +| id | bigint unsigned | NO | ID | +| tenant_id | bigint unsigned | NO | 테넌트 ID | +| group_id | int unsigned | NO | 그룹 ID | +| parent_type | varchar(50) | NO | 부모 엔티티 유형 | +| parent_id | bigint unsigned | NO | 부모 ID | +| child_type | varchar(50) | NO | 자식 엔티티 유형 | +| child_id | bigint unsigned | NO | 자식 ID | +| order_no | int | NO | 정렬 순서 | +| metadata | json | YES | 메타데이터 | + +--- + +## 3. 관계도 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ items │ +│ (통합 품목 테이블: FG/PT/SM/RM/CS) │ +│ │ +│ id, tenant_id, item_type, code, name, attributes(JSON) │ +└──────────────────────┬───────────────────────────────────────┘ + │ + ┌───────────┼───────────┬────────────────┐ + │ │ │ │ + ▼ ▼ ▼ ▼ + ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────┐ + │ item_ │ │ item_ │ │ item_ │ │ entity_ │ + │ details │ │bom_items │ │id_mappings│ │ relationships │ + │ │ │ │ │ │ │ │ + │ 1:1 관계 │ │ BOM 구성 │ │ 레거시 │ │ 일반 관계 │ + │ │ │ │ │ ID 매핑 │ │ (N:N 가능) │ + └──────────┘ └──────────┘ └──────────┘ └───────────────┘ + +┌─────────────────────────────────────────────────────────────┐ +│ 메타데이터 테이블 │ +├─────────────────┬─────────────────┬─────────────────────────┤ +│ item_sections │ item_fields │ item_pages │ +│ (섹션 정의) │ (필드 정의) │ (페이지 정의) │ +│ UI 그룹핑 용도 │ 동적 속성 정의 │ 품목 유형별 페이지 │ +└─────────────────┴─────────────────┴─────────────────────────┘ +``` + +--- + +## 4. 5130 → SAM 매핑 전략 + +### 4.1 테이블 매핑 + +| 5130 테이블 | → | SAM 테이블 | item_type | +|-------------|---|-----------|-----------| +| models | → | items | FG (완제품) | +| parts | → | items | PT (부품) | +| parts_sub | → | items | RM (원자재) | + +### 4.2 관계 매핑 + +| 5130 관계 | → | SAM 구현 | +|-----------|---|----------| +| parts.model_id → models | → | entity_relationships (parent=FG, child=PT) | +| parts_sub.part_id → parts | → | entity_relationships (parent=PT, child=RM) | +| 또는 | → | item_bom_items로 BOM 구성 | + +### 4.3 필드 매핑 + +| 5130 필드 | → | SAM 필드 | +|-----------|---|----------| +| model_name / part_name / subpart_name | → | items.name | +| spec | → | item_details.specification | +| unit | → | items.unit | +| quantity | → | item_bom_items.quantity | +| material | → | items.attributes.material | +| major_category | → | items.attributes.major_category | +| finishing_type | → | items.attributes.finishing_type | + +### 4.4 ID 추적 + +`item_id_mappings` 테이블 활용: +```sql +-- 마이그레이션 후 매핑 저장 +INSERT INTO item_id_mappings (source_table, source_id, item_id) +VALUES ('models', 12, 1001); -- models.model_id=12 → items.id=1001 +``` \ No newline at end of file diff --git a/projects/5130-migration/phase-3-mapping/field-mapping.md b/projects/5130-migration/phase-3-mapping/field-mapping.md new file mode 100644 index 0000000..46aa4f6 --- /dev/null +++ b/projects/5130-migration/phase-3-mapping/field-mapping.md @@ -0,0 +1,203 @@ +# 5130 → SAM 필드 매핑 + +> 작성일: 2025-12-21 +> 대상: 경동기업 (tenant_id: 287) + +--- + +## 1. 기본 설정 + +| 항목 | 값 | +|------|-----| +| tenant_id | 287 | +| 대상 회사 | 경동기업 | +| 제외 | 주일기업 (별도 테넌트로 추후 진행) | + +--- + +## 2. 테이블 매핑 + +### 2.1 models → items (완제품) + +| 5130 (models) | → | SAM (items) | 변환 규칙 | +|---------------|---|-------------|-----------| +| model_id | → | (item_id_mappings에 기록) | 매핑 추적용 | +| - | → | tenant_id | 고정값: 287 | +| - | → | item_type | 고정값: 'FG' | +| model_name | → | code | 그대로 (KSS01 등) | +| model_name | → | name | 그대로 | +| - | → | unit | 기본값: 'SET' | +| description | → | description | 그대로 | +| major_category | → | attributes.major_category | 스크린/스라트 | +| finishing_type | → | attributes.finishing_type | SUS마감/EGI마감 | +| guiderail_type | → | attributes.guiderail_type | 그대로 | +| is_deleted | → | deleted_at | 1이면 현재시간, 0이면 NULL | +| created_at | → | created_at | 그대로 | +| updated_at | → | updated_at | 그대로 | + +**items.attributes JSON 구조:** +```json +{ + "major_category": "스크린", + "finishing_type": "SUS마감", + "guiderail_type": "일반형", + "source": "5130", + "source_table": "models", + "source_id": 12 +} +``` + +### 2.2 parts → items (부품) + +| 5130 (parts) | → | SAM (items) | 변환 규칙 | +|--------------|---|-------------|-----------| +| part_id | → | (item_id_mappings에 기록) | 매핑 추적용 | +| - | → | tenant_id | 고정값: 287 | +| - | → | item_type | 고정값: 'PT' | +| part_name | → | code | 정규화 필요 (공백→언더스코어) | +| part_name | → | name | 그대로 | +| unit | → | unit | 그대로 (SET 등) | +| spec | → | attributes.spec | 규격 (120*70 등) | +| memo | → | description | 그대로 | +| unitprice | → | attributes.unit_price | varchar→decimal 변환 | +| img_url | → | attributes.image_url | 그대로 | +| is_deleted | → | deleted_at | 변환 | +| created_at | → | created_at | 그대로 | +| updated_at | → | updated_at | 그대로 | + +**items.attributes JSON 구조:** +```json +{ + "spec": "120*70", + "unit_price": 15000, + "image_url": "/img/parts/xxx.jpg", + "source": "5130", + "source_table": "parts", + "source_id": 49 +} +``` + +### 2.3 parts_sub → items (원자재) + +| 5130 (parts_sub) | → | SAM (items) | 변환 규칙 | +|------------------|---|-------------|-----------| +| subpart_id | → | (item_id_mappings에 기록) | 매핑 추적용 | +| - | → | tenant_id | 고정값: 287 | +| - | → | item_type | 고정값: 'RM' | +| subpart_name | → | code | 정규화 | +| subpart_name | → | name | 그대로 | +| - | → | unit | 기본값: 'EA' | +| material | → | attributes.material | SUS 1.2T 등 | +| bendSum | → | attributes.bend_sum | varchar→decimal | +| plateSum | → | attributes.plate_sum | varchar→decimal | +| finalSum | → | attributes.final_sum | varchar→decimal | +| unitPrice | → | attributes.unit_price | varchar→decimal | +| computedPrice | → | attributes.computed_price | varchar→decimal | +| lineTotal | → | attributes.line_total | varchar→decimal | +| image_url | → | attributes.image_url | 그대로 | +| is_deleted | → | deleted_at | 변환 | +| created_at | → | created_at | 그대로 | +| updated_at | → | updated_at | 그대로 | + +**items.attributes JSON 구조:** +```json +{ + "material": "SUS 1.2T", + "bend_sum": 5000, + "plate_sum": 3000, + "final_sum": 8000, + "unit_price": 1500, + "computed_price": 1500, + "line_total": 15000, + "image_url": "/img/sub/xxx.jpg", + "source": "5130", + "source_table": "parts_sub", + "source_id": 64 +} +``` + +--- + +## 3. 관계 매핑 + +### 3.1 models ↔ parts 관계 + +**entity_relationships 테이블 사용:** + +| 필드 | 값 | +|------|-----| +| tenant_id | 287 | +| parent_type | 'items' | +| parent_id | (models에서 생성된 items.id) | +| child_type | 'items' | +| child_id | (parts에서 생성된 items.id) | +| order_no | parts.part_id 순서 | +| metadata | {"quantity": parts.quantity, "relation": "bom"} | + +### 3.2 parts ↔ parts_sub 관계 + +**entity_relationships 테이블 사용:** + +| 필드 | 값 | +|------|-----| +| tenant_id | 287 | +| parent_type | 'items' | +| parent_id | (parts에서 생성된 items.id) | +| child_type | 'items' | +| child_id | (parts_sub에서 생성된 items.id) | +| order_no | parts_sub.subpart_id 순서 | +| metadata | {"quantity": parts_sub.quantity, "relation": "bom"} | + +--- + +## 4. ID 매핑 (item_id_mappings) + +마이그레이션 추적을 위해 원본 ID 기록: + +| source_table | source_id | item_id | +|--------------|-----------|---------| +| models | 12 | (생성된 ID) | +| parts | 49 | (생성된 ID) | +| parts_sub | 64 | (생성된 ID) | + +--- + +## 5. 코드 생성 규칙 + +### 5.1 items.code 생성 + +| item_type | 코드 패턴 | 예시 | +|-----------|----------|------| +| FG (완제품) | 원본 model_name 유지 | KSS01, KSE01 | +| PT (부품) | PT-{정규화된 이름} | PT-UPPER_BRACKET | +| RM (원자재) | RM-{정규화된 이름} | RM-SUS_1_2T_FRONT | + +### 5.2 정규화 규칙 +- 한글 → 영문 변환 (또는 유지) +- 공백 → 언더스코어 +- 특수문자 제거 +- 대문자 변환 + +--- + +## 6. 타입 변환 규칙 + +| 원본 타입 | 대상 타입 | 변환 로직 | +|----------|----------|----------| +| varchar (가격) | decimal | 숫자만 추출, NULL이면 0 | +| tinyint (is_deleted) | timestamp (deleted_at) | 1→now(), 0→NULL | +| enum (major_category) | varchar (JSON) | 그대로 저장 | +| datetime | timestamp | 그대로 | + +--- + +## 7. 마이그레이션 순서 + +1. **models → items** (FG) - 18건 +2. **parts → items** (PT) - 37건 +3. **parts_sub → items** (RM) - 134건 +4. **models↔parts 관계 → entity_relationships** +5. **parts↔parts_sub 관계 → entity_relationships** +6. **item_id_mappings 기록** + +**총 예상:** items 189건, entity_relationships 171건