docs: 5130 → SAM 품목 마이그레이션 문서 추가

- 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 <noreply@anthropic.com>
This commit is contained in:
2025-12-21 13:49:28 +09:00
parent 741e6677ab
commit e217266376
5 changed files with 1073 additions and 0 deletions

View File

@@ -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 |

View File

@@ -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

View File

@@ -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 변환

View File

@@ -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
```

View File

@@ -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건