docs: [bom] BOM V2 범용 멀티테넌트 아키텍처 설계 문서 추가
- V1 한계점 진단 (3중 병렬, 버전 없음, 업종 종속) - V2 관계형 BOM 구조 설계 (bom_headers, bom_lines, bom_substitutes) - 10종 품목유형 확장 (SA, WIP, PH, BP, SV 추가) - 버전/팬텀/대체품목/공정연동/유효기간 설계 - 업종별 프리셋 (블라인드, 전자, 식품, 가구, 단순조립) - 4단계 마이그레이션 로드맵 - INDEX.md 등록
This commit is contained in:
2
INDEX.md
2
INDEX.md
@@ -20,6 +20,7 @@
|
||||
| Blade+React | `dev/standards/blade-react-policy.md` | Blade JSX 이중 중괄호 충돌 방지 |
|
||||
| 이메일 연동 | `dev/guides/tenant-email-integration-guide.md` | 테넌트 메일 연동, SMTP 프리셋, MNG 관리 |
|
||||
| 품목관리 | `rules/item-policy.md` | 품목 정책 |
|
||||
| BOM V2 설계 | `plans/bom-v2-universal-architecture-plan.md` | 범용 멀티테넌트 BOM V2 아키텍처 |
|
||||
| 단가관리 | `rules/pricing-policy.md` | 6 Depth 단가 체계, 흐름도, 계산공식, 버전관리 개선방향 |
|
||||
| 단가 버전관리 기획 | `dev/dev_plans/price-version-management-plan.md` | 단가 버전 그룹, 일괄변경, 영향분석, 적용 워크플로우 |
|
||||
| 견적관리 | `features/quotes/README.md` | 견적 시스템, BOM 계산 |
|
||||
@@ -375,6 +376,7 @@ DB 도메인별:
|
||||
| [bom-tree-3level-react-request.md](plans/bom-tree-3level-react-request.md) | BOM 트리 3단계 그룹 표시 React 구현 요청 (API 완료, 카테고리 접힘/펼침) |
|
||||
| [item-list-search-state-preservation.md](plans/item-list-search-state-preservation.md) | 품목관리 검색 상태 보존 UX 개선 요청 (router.back + URL searchParams 동기화) |
|
||||
| [optimal-stock-management-plan.md](plans/optimal-stock-management-plan.md) | 적정재고 관리 기능 기획 (안전재고+최대재고 범위 기반, 상태 확장) |
|
||||
| [bom-v2-universal-architecture-plan.md](plans/bom-v2-universal-architecture-plan.md) | BOM V2 범용 멀티테넌트 아키텍처 설계 (V1 한계 분석, 관계형 BOM, 버전/팬텀/대체/공정 연동) |
|
||||
|
||||
### frontend/integration/ — 프론트엔드 개발 가이드
|
||||
|
||||
|
||||
824
plans/bom-v2-universal-architecture-plan.md
Normal file
824
plans/bom-v2-universal-architecture-plan.md
Normal file
@@ -0,0 +1,824 @@
|
||||
# BOM V2 범용 멀티테넌트 아키텍처 설계
|
||||
|
||||
> **작성일**: 2026-03-22
|
||||
> **상태**: 설계 중
|
||||
> **담당**: R&D실
|
||||
> **목표**: 어떤 업종/회사도 수용 가능한 확장형 BOM 시스템
|
||||
|
||||
---
|
||||
|
||||
## 1. V1 현황 진단
|
||||
|
||||
### 1.1 현재 구조 (3중 병렬)
|
||||
|
||||
```
|
||||
V1 BOM 시스템
|
||||
├── Product BOM (product_components) ← 레거시, 폐기 진행 중
|
||||
├── Design BOM (bom_templates) ← 수식 산출용 (활성)
|
||||
└── Item BOM (items.bom JSON) ← 현재 표준
|
||||
```
|
||||
|
||||
| 시스템 | 저장 방식 | 계층 | 버전 | 상태 |
|
||||
|--------|---------|:----:|:----:|------|
|
||||
| Product BOM | 관계형 (product_components) | N-Level | 없음 | 폐기 중 |
|
||||
| Design BOM | 관계형 (bom_template_items) | 1-Level | 모델 버전 | 수식 전용 |
|
||||
| Item BOM | JSON (items.bom) | 1-Level* | 없음 | **표준** |
|
||||
|
||||
> *Item BOM은 저장이 1-Level이지만, 자식의 BOM을 재귀 탐색하여 트리를 구성한다.
|
||||
|
||||
### 1.2 V1 한계점
|
||||
|
||||
| 분류 | 한계 | 영향 |
|
||||
|------|------|------|
|
||||
| **구조** | BOM이 JSON 평탄 저장 → 다단계 재귀 탐색 필요 | 성능 저하, 순환 참조 위험 |
|
||||
| **구조** | 3개 BOM 시스템 병렬 → 데이터 일관성 유지 어려움 | 유지보수 비용 |
|
||||
| **버전** | BOM 버전/리비전 없음 (덮어쓰기) | 변경 이력 추적 불가 |
|
||||
| **유형** | item_type 5종 고정 (FG/PT/SM/RM/CS) | 반제품(WIP), 팬텀 등 미지원 |
|
||||
| **수식** | 산출 수식이 경동기업 제품에 하드코딩 | 다른 업종 적용 불가 |
|
||||
| **공정** | BOM-공정(Routing) 연동 없음 | 공정별 자재 투입 관리 불가 |
|
||||
| **대체** | 대체품목(Substitute) 미지원 | 자재 부족 시 대응 불가 |
|
||||
| **유효** | BOM 유효기간(Effectivity) 없음 | 설계 변경 시점 관리 불가 |
|
||||
| **수율** | 수율/로스율이 Design BOM에만 존재 | Item BOM에서 로스 관리 불가 |
|
||||
| **원가** | BOM 기반 원가 계산 구조 없음 | 표준원가 산출 불가 |
|
||||
| **승인** | BOM 승인 워크플로우 없음 | 무검증 BOM 변경 가능 |
|
||||
| **비교** | BOM 간 diff/비교 기능 제한적 | 설계 변경 영향 분석 어려움 |
|
||||
|
||||
### 1.3 V1에서 유지할 것
|
||||
|
||||
| 항목 | 이유 |
|
||||
|------|------|
|
||||
| `items` 통합 테이블 | Products+Materials 단일화 완료, 역행 불필요 |
|
||||
| `tenant_id` + `BelongsToTenant` | 멀티테넌시 기반 확립 |
|
||||
| `options` JSON 정책 | 확장성 확보 |
|
||||
| `BomTemplate` 수식 엔진 | 파라미터 기반 산출 유지 |
|
||||
| Category 계층 분류 | 기존 카테고리 시스템 활용 |
|
||||
|
||||
---
|
||||
|
||||
## 2. V2 설계 원칙
|
||||
|
||||
### 2.1 핵심 원칙
|
||||
|
||||
```
|
||||
P1. 모든 업종 수용 — 이산/공정/조립/혼합 제조 전부 지원
|
||||
P2. 테넌트별 자율 — BOM 깊이, 유형, 수식을 테넌트가 정의
|
||||
P3. 단일 BOM 엔진 — 3중 병렬 → 1개 통합 BOM 테이블
|
||||
P4. 버전 필수 — 모든 BOM 변경은 리비전으로 관리
|
||||
P5. 하위 호환 — V1 JSON BOM 데이터 무손실 마이그레이션
|
||||
```
|
||||
|
||||
### 2.2 지원 대상 업종
|
||||
|
||||
| 업종 | BOM 특성 | V2 대응 |
|
||||
|------|---------|---------|
|
||||
| **블라인드/스크린** (현재) | 수식 기반, 가변 사이즈 | 수식 엔진 유지 |
|
||||
| **기계 부품** | 다단계 조립, 가공 공정 | N-Level + Routing |
|
||||
| **전자/반도체** | 대체품목, ECN 관리 | Substitute + Effectivity |
|
||||
| **식품/화학** | 배합비, 수율, 부산물 | Formula BOM + Co-product |
|
||||
| **건설/플랜트** | 프로젝트별 BOM, 대량 자재 | Project BOM + Bulk |
|
||||
| **가구/인테리어** | 옵션 조합, 커스텀 | Configurable BOM |
|
||||
| **의류/섬유** | 사이즈별 BOM, 색상별 원단 | Variant BOM |
|
||||
|
||||
---
|
||||
|
||||
## 3. V2 데이터 모델
|
||||
|
||||
### 3.1 핵심 테이블 설계
|
||||
|
||||
```
|
||||
V2 BOM 테이블 구조
|
||||
|
||||
items (기존 유지 + 확장)
|
||||
├── item_type 확장: FG, SA, PT, WIP, PH, SM, RM, CS, BP, SV
|
||||
└── bom 컬럼: 제거 (관계형으로 이관)
|
||||
|
||||
bom_headers (신규 — BOM 헤더/버전)
|
||||
├── item_id → items
|
||||
├── revision (REV.01, REV.02 ...)
|
||||
├── status (DRAFT → PENDING → APPROVED → ACTIVE → OBSOLETE)
|
||||
├── effective_from / effective_to
|
||||
└── bom_type (STANDARD | ENGINEERING | CONFIGURABLE | FORMULA)
|
||||
|
||||
bom_lines (신규 — BOM 라인/구성품)
|
||||
├── bom_header_id → bom_headers
|
||||
├── child_item_id → items
|
||||
├── quantity + quantity_formula
|
||||
├── waste_rate (로스율)
|
||||
├── operation_id → operations (공정 연결)
|
||||
├── effective_from / effective_to (라인별 유효기간)
|
||||
└── options JSON (확장 속성)
|
||||
|
||||
bom_substitutes (신규 — 대체품목)
|
||||
├── bom_line_id → bom_lines
|
||||
├── substitute_item_id → items
|
||||
├── priority (대체 우선순위)
|
||||
└── conversion_factor (환산 계수)
|
||||
|
||||
operations (신규 — 공정/라우팅)
|
||||
├── item_id → items
|
||||
├── sequence (공정 순서)
|
||||
├── process_id → processes (공정 마스터)
|
||||
├── setup_time, run_time, wait_time
|
||||
└── work_center_id (작업장)
|
||||
```
|
||||
|
||||
### 3.2 ERD 관계
|
||||
|
||||
```
|
||||
items ─────────────────────────────────────────────────
|
||||
│ (1:N) │
|
||||
▼ │
|
||||
bom_headers ────────────────────────── │
|
||||
│ (1:N) │ │
|
||||
▼ │ │
|
||||
bom_lines ─── (N:1) ──→ items ◄─────┘ │
|
||||
│ (1:N) │ │
|
||||
▼ │ (N:1) │
|
||||
bom_substitutes ▼ │
|
||||
operations ─── (N:1) ──→ processes │
|
||||
│ │
|
||||
└── (N:1) ──→ work_centers │
|
||||
│
|
||||
bom_templates (기존 유지) │
|
||||
└── 수식 산출 → bom_headers 자동 생성 ───────────────┘
|
||||
```
|
||||
|
||||
### 3.3 items.item_type 확장
|
||||
|
||||
| 코드 | 한글 | 설명 | V1 | V2 |
|
||||
|------|------|------|:--:|:--:|
|
||||
| `FG` | 완제품 | 판매 가능한 최종 제품 | O | O |
|
||||
| `SA` | 반조립품 | 중간 조립품 (재고 관리됨) | - | **신규** |
|
||||
| `PT` | 부품 | 구성 부품 | O | O |
|
||||
| `WIP` | 재공품 | 가공 중인 중간 산출물 | - | **신규** |
|
||||
| `PH` | 팬텀 | 가상 그룹 (재고 없음, BOM 전개 시 투과) | - | **신규** |
|
||||
| `SM` | 부자재 | 보조 자재 | O | O |
|
||||
| `RM` | 원자재 | 주요 원료 | O | O |
|
||||
| `CS` | 소모품 | 일회성 소모 자재 | O | O |
|
||||
| `BP` | 부산물 | 생산 시 발생하는 부산물 | - | **신규** |
|
||||
| `SV` | 서비스 | 외주 가공, 검사비 등 비물리 항목 | - | **신규** |
|
||||
|
||||
> 테넌트별로 사용할 유형을 선택할 수 있다. 블라인드 업체는 FG/PT/SM/RM/CS만, 전자업체는 SA/PH까지 활성화.
|
||||
|
||||
### 3.4 bom_headers 상세
|
||||
|
||||
```sql
|
||||
CREATE TABLE bom_headers (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
tenant_id BIGINT UNSIGNED NOT NULL,
|
||||
item_id BIGINT UNSIGNED NOT NULL, -- 부모 품목
|
||||
revision VARCHAR(20) NOT NULL DEFAULT 'REV.01',
|
||||
bom_type VARCHAR(20) NOT NULL DEFAULT 'STANDARD',
|
||||
-- STANDARD: 일반 BOM
|
||||
-- ENGINEERING: 설계용 (비생산)
|
||||
-- CONFIGURABLE: 옵션 조합 BOM
|
||||
-- FORMULA: 배합/수식 BOM
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'DRAFT',
|
||||
-- DRAFT → PENDING → APPROVED → ACTIVE → OBSOLETE
|
||||
effective_from DATE NULL, -- 유효 시작
|
||||
effective_to DATE NULL, -- 유효 종료
|
||||
base_qty DECIMAL(18,6) NOT NULL DEFAULT 1, -- 기준 수량
|
||||
base_unit VARCHAR(20) NULL, -- 기준 단위
|
||||
description TEXT NULL,
|
||||
approved_by BIGINT UNSIGNED NULL, -- 승인자
|
||||
approved_at DATETIME NULL,
|
||||
source_template_id BIGINT UNSIGNED NULL, -- Design BOM 연결
|
||||
options JSON NULL, -- 확장 속성
|
||||
created_by BIGINT UNSIGNED NULL,
|
||||
updated_by BIGINT UNSIGNED NULL,
|
||||
created_at TIMESTAMP NULL,
|
||||
updated_at TIMESTAMP NULL,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
|
||||
UNIQUE KEY uq_bom_tenant_item_rev (tenant_id, item_id, revision, deleted_at),
|
||||
INDEX idx_bom_tenant_item (tenant_id, item_id),
|
||||
INDEX idx_bom_tenant_status (tenant_id, status),
|
||||
INDEX idx_bom_effective (tenant_id, effective_from, effective_to)
|
||||
);
|
||||
```
|
||||
|
||||
### 3.5 bom_lines 상세
|
||||
|
||||
```sql
|
||||
CREATE TABLE bom_lines (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
tenant_id BIGINT UNSIGNED NOT NULL,
|
||||
bom_header_id BIGINT UNSIGNED NOT NULL,
|
||||
child_item_id BIGINT UNSIGNED NOT NULL, -- 자식 품목
|
||||
quantity DECIMAL(18,6) NOT NULL DEFAULT 1, -- 소요량
|
||||
quantity_formula VARCHAR(500) NULL, -- 수식 (예: "W1 * H1 / 1000000")
|
||||
unit VARCHAR(20) NULL,
|
||||
waste_rate DECIMAL(9,6) NOT NULL DEFAULT 0, -- 로스율 (0.05 = 5%)
|
||||
category VARCHAR(100) NULL, -- 카테고리 그룹명
|
||||
operation_id BIGINT UNSIGNED NULL, -- 공정 연결
|
||||
effective_from DATE NULL, -- 라인별 유효 시작
|
||||
effective_to DATE NULL, -- 라인별 유효 종료
|
||||
is_phantom TINYINT(1) NOT NULL DEFAULT 0, -- 팬텀 여부 (BOM 전개 시 투과)
|
||||
supply_type VARCHAR(20) DEFAULT 'STOCK', -- STOCK | PURCHASE | SUBCONTRACT
|
||||
sort_order INT NOT NULL DEFAULT 0,
|
||||
notes VARCHAR(500) NULL,
|
||||
options JSON NULL, -- 확장 속성
|
||||
created_by BIGINT UNSIGNED NULL,
|
||||
updated_by BIGINT UNSIGNED NULL,
|
||||
created_at TIMESTAMP NULL,
|
||||
updated_at TIMESTAMP NULL,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
|
||||
INDEX idx_bl_tenant_header (tenant_id, bom_header_id),
|
||||
INDEX idx_bl_child (child_item_id),
|
||||
INDEX idx_bl_operation (operation_id),
|
||||
INDEX idx_bl_effective (effective_from, effective_to)
|
||||
);
|
||||
```
|
||||
|
||||
### 3.6 bom_substitutes 상세
|
||||
|
||||
```sql
|
||||
CREATE TABLE bom_substitutes (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
tenant_id BIGINT UNSIGNED NOT NULL,
|
||||
bom_line_id BIGINT UNSIGNED NOT NULL,
|
||||
substitute_item_id BIGINT UNSIGNED NOT NULL, -- 대체 품목
|
||||
priority INT NOT NULL DEFAULT 1, -- 대체 우선순위 (1=최우선)
|
||||
conversion_factor DECIMAL(12,6) NOT NULL DEFAULT 1, -- 환산 계수
|
||||
effective_from DATE NULL,
|
||||
effective_to DATE NULL,
|
||||
notes VARCHAR(255) NULL,
|
||||
options JSON NULL,
|
||||
created_at TIMESTAMP NULL,
|
||||
updated_at TIMESTAMP NULL,
|
||||
|
||||
INDEX idx_bs_tenant_line (tenant_id, bom_line_id),
|
||||
UNIQUE KEY uq_bs_line_sub (bom_line_id, substitute_item_id)
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. BOM 유형별 동작
|
||||
|
||||
### 4.1 STANDARD BOM (표준 BOM)
|
||||
|
||||
가장 일반적인 형태. 고정 수량 기반.
|
||||
|
||||
```
|
||||
FG-001 (스크린 제품) [REV.02, ACTIVE, 2026-01-01~]
|
||||
├── [주자재] RM-001 스크린 원단 x10.65 m² (로스 5%)
|
||||
├── [모터] PT-001 모터 150K x1 EA
|
||||
├── [제어기] PT-002 제어기 노출형 x1 EA
|
||||
├── [절곡품] WIP-001 케이스 500*380 x3.22 m → 공정: 절곡
|
||||
├── [절곡품] WIP-002 마구리 505*385 x1 EA → 공정: 절곡
|
||||
├── [부자재] SM-001 감기샤프트 x1 EA
|
||||
├── [검사비] SV-001 검사비 x1 EA
|
||||
└── [대체] PT-001 → PT-001-B 모터 200K (priority=1, factor=1.0)
|
||||
```
|
||||
|
||||
### 4.2 FORMULA BOM (수식 BOM)
|
||||
|
||||
파라미터 입력 → 수식 평가 → 수량 자동 계산. 기존 Design BOM의 발전형.
|
||||
|
||||
```
|
||||
FG-KSS02 (스크린 SUS 측면형) [FORMULA]
|
||||
├── 파라미터: W0=3000, H0=3000, QTY=1, MP=single
|
||||
├── 변수계산: W1=W0+140, H1=H0+350, M=W1*H1/1e6, K=M*2+(W0/1000)*14.17
|
||||
│
|
||||
├── RM-슬랫 qty_formula="M" → 10.65 m²
|
||||
├── PT-모터 qty_formula="1" → 1 EA
|
||||
├── WIP-케이스 qty_formula="W1/1000" → 3.14 m
|
||||
├── SM-샤프트 qty_formula="CEIL(H1/2000)" → 2 EA
|
||||
└── SV-검사 qty_formula="1" → 1 EA
|
||||
```
|
||||
|
||||
> 수식 평가 후 결과를 STANDARD BOM으로 스냅샷 저장 가능 (V1의 "BOM 저장" 기능 유지).
|
||||
|
||||
### 4.3 CONFIGURABLE BOM (구성형 BOM)
|
||||
|
||||
옵션 조합에 따라 구성이 달라지는 BOM. 가구/의류/맞춤 제품에 적합.
|
||||
|
||||
```
|
||||
FG-DESK (사무용 책상) [CONFIGURABLE]
|
||||
├── [공통] PT-프레임 x1 EA — 항상 포함
|
||||
├── [공통] SM-나사세트 x1 SET — 항상 포함
|
||||
│
|
||||
├── [옵션: 상판 재질]
|
||||
│ ├── 원목 → RM-원목상판 x1 EA
|
||||
│ ├── MDF → RM-MDF상판 x1 EA
|
||||
│ └── 유리 → RM-유리상판 x1 EA + SM-흡착패드 x4 EA
|
||||
│
|
||||
└── [옵션: 다리 높이]
|
||||
├── 표준(720mm) → PT-다리-720 x4 EA
|
||||
└── 높은(900mm) → PT-다리-900 x4 EA
|
||||
```
|
||||
|
||||
### 4.4 ENGINEERING BOM (설계 BOM)
|
||||
|
||||
생산 투입 전 설계 단계 BOM. 승인 후 STANDARD로 전환.
|
||||
|
||||
```
|
||||
ENGINEERING BOM (설계팀)
|
||||
│ 검토 → 승인
|
||||
▼
|
||||
STANDARD BOM (생산팀)
|
||||
│ ECN (설계 변경)
|
||||
▼
|
||||
새 REVISION 생성 (REV.02)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. BOM 버전 관리
|
||||
|
||||
### 5.1 리비전 워크플로우
|
||||
|
||||
```
|
||||
REV.01 (DRAFT)
|
||||
│ 편집 완료
|
||||
▼
|
||||
REV.01 (PENDING) ← 승인 요청
|
||||
│ 승인자 확인
|
||||
▼
|
||||
REV.01 (APPROVED) ← 승인 완료
|
||||
│ 유효기간 도래
|
||||
▼
|
||||
REV.01 (ACTIVE) ← 생산에 사용
|
||||
│ 설계 변경 발생
|
||||
▼
|
||||
REV.01 (OBSOLETE) ← 비활성화
|
||||
REV.02 (DRAFT) 생성 ← 새 리비전
|
||||
```
|
||||
|
||||
### 5.2 유효기간 관리
|
||||
|
||||
```
|
||||
REV.01 ────────[2025-01-01 ~ 2026-06-30]────────
|
||||
REV.02 [2026-07-01 ~ ]──────────────
|
||||
↑
|
||||
설계 변경 적용일
|
||||
```
|
||||
|
||||
- 특정 날짜에 유효한 BOM 조회: `WHERE effective_from <= ? AND (effective_to IS NULL OR effective_to >= ?)`
|
||||
- 라인별 유효기간: 부품 단종/교체 시 개별 라인 종료
|
||||
|
||||
### 5.3 BOM 비교 (Diff)
|
||||
|
||||
```json
|
||||
{
|
||||
"comparison": "REV.01 vs REV.02",
|
||||
"added": [
|
||||
{ "item": "PT-003 신규부품", "qty": 2 }
|
||||
],
|
||||
"removed": [
|
||||
{ "item": "PT-002 구부품", "qty": 1 }
|
||||
],
|
||||
"changed": [
|
||||
{ "item": "RM-001 원단", "qty_before": 10.0, "qty_after": 10.65, "reason": "로스율 반영" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 팬텀(Phantom) 품목
|
||||
|
||||
### 6.1 개념
|
||||
|
||||
팬텀 품목은 **재고로 관리하지 않는 가상 그룹**이다. BOM 전개(Explosion) 시 팬텀은 "투과"되어 하위 구성품이 직접 상위로 올라간다.
|
||||
|
||||
### 6.2 V1 → V2 매핑
|
||||
|
||||
V1의 `item_type: CAT` (카테고리 그룹)가 V2의 팬텀에 해당한다.
|
||||
|
||||
```
|
||||
V1 (가상 CAT 노드):
|
||||
FG-001
|
||||
├── [CAT] 주자재 (가상 — DB에 없음, 코드로 생성)
|
||||
│ └── RM-001 스크린 원단
|
||||
└── [CAT] 모터 (가상)
|
||||
└── PT-001 모터
|
||||
|
||||
V2 (팬텀 품목):
|
||||
FG-001
|
||||
├── PH-주자재 (팬텀 — items 테이블에 실체 있음)
|
||||
│ └── RM-001 스크린 원단
|
||||
└── PH-모터 (팬텀)
|
||||
└── PT-001 모터
|
||||
|
||||
BOM 전개 결과 (MRP):
|
||||
FG-001 → RM-001, PT-001 (팬텀 투과)
|
||||
```
|
||||
|
||||
### 6.3 팬텀 활용
|
||||
|
||||
| 용도 | 설명 |
|
||||
|------|------|
|
||||
| **그룹화** | V1의 카테고리 그룹을 구조화 |
|
||||
| **중간조립 생략** | 재고 불필요한 중간 단계 |
|
||||
| **공통 부품군** | 여러 FG에서 공유하는 부품 묶음 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 공정-BOM 연동 (Routing)
|
||||
|
||||
### 7.1 공정 마스터
|
||||
|
||||
```sql
|
||||
CREATE TABLE processes (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
tenant_id BIGINT UNSIGNED NOT NULL,
|
||||
code VARCHAR(50) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
type VARCHAR(50) NULL, -- FABRICATION | ASSEMBLY | INSPECTION | SUBCONTRACT
|
||||
options JSON NULL,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP NULL,
|
||||
updated_at TIMESTAMP NULL,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
|
||||
UNIQUE KEY uq_process_tenant_code (tenant_id, code, deleted_at)
|
||||
);
|
||||
```
|
||||
|
||||
### 7.2 공정 라우팅
|
||||
|
||||
```sql
|
||||
CREATE TABLE operations (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
tenant_id BIGINT UNSIGNED NOT NULL,
|
||||
item_id BIGINT UNSIGNED NOT NULL, -- 대상 품목
|
||||
bom_header_id BIGINT UNSIGNED NULL, -- BOM과 연결 (선택)
|
||||
sequence INT NOT NULL, -- 공정 순서 (10, 20, 30...)
|
||||
process_id BIGINT UNSIGNED NOT NULL, -- 공정 마스터
|
||||
work_center_id BIGINT UNSIGNED NULL, -- 작업장/설비
|
||||
setup_time DECIMAL(10,2) DEFAULT 0, -- 준비 시간 (분)
|
||||
run_time DECIMAL(10,2) DEFAULT 0, -- 가동 시간 (분/단위)
|
||||
wait_time DECIMAL(10,2) DEFAULT 0, -- 대기 시간 (분)
|
||||
description VARCHAR(500) NULL,
|
||||
options JSON NULL,
|
||||
created_at TIMESTAMP NULL,
|
||||
updated_at TIMESTAMP NULL,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
|
||||
INDEX idx_op_tenant_item (tenant_id, item_id),
|
||||
INDEX idx_op_sequence (item_id, sequence)
|
||||
);
|
||||
```
|
||||
|
||||
### 7.3 공정별 자재 투입
|
||||
|
||||
```
|
||||
FG-001 스크린 제품
|
||||
공정 10: 원단 재단 → RM-001 원단 (이 공정에서 투입)
|
||||
공정 20: 절곡 가공 → WIP-001 케이스, WIP-002 마구리
|
||||
공정 30: 조립 → PT-001 모터, PT-002 제어기, SM-001 샤프트
|
||||
공정 40: 검사 → SV-001 검사비
|
||||
공정 50: 포장 → SM-002 포장재
|
||||
```
|
||||
|
||||
`bom_lines.operation_id`로 각 자재가 어느 공정에서 투입되는지 연결한다.
|
||||
|
||||
---
|
||||
|
||||
## 8. 테넌트별 BOM 설정
|
||||
|
||||
### 8.1 테넌트 BOM 설정 (tenant_bom_settings)
|
||||
|
||||
```sql
|
||||
CREATE TABLE tenant_bom_settings (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
tenant_id BIGINT UNSIGNED NOT NULL UNIQUE,
|
||||
-- 활성화할 품목 유형
|
||||
enabled_item_types JSON NOT NULL DEFAULT '["FG","PT","SM","RM","CS"]',
|
||||
-- 활성화할 BOM 유형
|
||||
enabled_bom_types JSON NOT NULL DEFAULT '["STANDARD"]',
|
||||
-- BOM 최대 깊이
|
||||
max_bom_depth INT NOT NULL DEFAULT 10,
|
||||
-- 승인 워크플로우 사용 여부
|
||||
require_approval BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
-- 유효기간 관리 사용 여부
|
||||
use_effectivity BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
-- 대체품목 사용 여부
|
||||
use_substitutes BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
-- 공정(Routing) 연동 여부
|
||||
use_routing BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
-- 로스율 관리 여부
|
||||
use_waste_rate BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
-- 팬텀 품목 사용 여부
|
||||
use_phantom BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
-- 수식 BOM 사용 여부
|
||||
use_formula_bom BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
-- 카테고리 그룹 표시 방식
|
||||
category_display VARCHAR(20) DEFAULT 'FOLDER', -- FOLDER | FLAT | NONE
|
||||
-- 커스텀 BOM 라인 필드 (테넌트별 확장)
|
||||
custom_line_fields JSON NULL,
|
||||
options JSON NULL,
|
||||
created_at TIMESTAMP NULL,
|
||||
updated_at TIMESTAMP NULL
|
||||
);
|
||||
```
|
||||
|
||||
### 8.2 업종별 프리셋
|
||||
|
||||
```json
|
||||
{
|
||||
"presets": {
|
||||
"blind_screen": {
|
||||
"label": "블라인드/스크린 제조",
|
||||
"enabled_item_types": ["FG", "PT", "WIP", "SM", "RM", "CS", "SV"],
|
||||
"enabled_bom_types": ["STANDARD", "FORMULA"],
|
||||
"max_bom_depth": 5,
|
||||
"use_formula_bom": true,
|
||||
"use_waste_rate": true,
|
||||
"use_routing": true,
|
||||
"category_display": "FOLDER"
|
||||
},
|
||||
"electronics": {
|
||||
"label": "전자/반도체",
|
||||
"enabled_item_types": ["FG", "SA", "PT", "PH", "SM", "RM", "CS"],
|
||||
"enabled_bom_types": ["STANDARD", "ENGINEERING"],
|
||||
"max_bom_depth": 15,
|
||||
"require_approval": true,
|
||||
"use_effectivity": true,
|
||||
"use_substitutes": true,
|
||||
"use_phantom": true
|
||||
},
|
||||
"food_chemical": {
|
||||
"label": "식품/화학",
|
||||
"enabled_item_types": ["FG", "PT", "RM", "CS", "BP"],
|
||||
"enabled_bom_types": ["STANDARD", "FORMULA"],
|
||||
"use_formula_bom": true,
|
||||
"use_waste_rate": true,
|
||||
"category_display": "FLAT"
|
||||
},
|
||||
"furniture": {
|
||||
"label": "가구/인테리어",
|
||||
"enabled_item_types": ["FG", "SA", "PT", "SM", "RM"],
|
||||
"enabled_bom_types": ["STANDARD", "CONFIGURABLE"],
|
||||
"max_bom_depth": 5
|
||||
},
|
||||
"simple_assembly": {
|
||||
"label": "단순 조립",
|
||||
"enabled_item_types": ["FG", "PT", "SM", "RM", "CS"],
|
||||
"enabled_bom_types": ["STANDARD"],
|
||||
"max_bom_depth": 3,
|
||||
"category_display": "FLAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. API 설계
|
||||
|
||||
### 9.1 엔드포인트 구조
|
||||
|
||||
```
|
||||
/api/v2/items/{itemId}/bom/
|
||||
├── GET / BOM 헤더 목록 (리비전 이력)
|
||||
├── POST / BOM 헤더 생성 (새 리비전)
|
||||
├── GET /{bomId} BOM 상세 (헤더 + 라인)
|
||||
├── PUT /{bomId} BOM 헤더 수정
|
||||
├── DELETE /{bomId} BOM 삭제 (DRAFT만)
|
||||
│
|
||||
├── GET /{bomId}/lines BOM 라인 목록
|
||||
├── POST /{bomId}/lines 라인 추가
|
||||
├── PUT /{bomId}/lines/bulk 라인 일괄 업서트
|
||||
├── PUT /{bomId}/lines/{id} 라인 수정
|
||||
├── DELETE /{bomId}/lines/{id} 라인 삭제
|
||||
│
|
||||
├── GET /{bomId}/tree BOM 트리 (재귀, 팬텀 투과 옵션)
|
||||
├── GET /{bomId}/flat BOM 전개 (Explosion, 평탄화)
|
||||
├── GET /{bomId}/where-used 역전개 (이 품목을 사용하는 BOM)
|
||||
│
|
||||
├── POST /{bomId}/approve 승인 요청
|
||||
├── POST /{bomId}/activate 활성화
|
||||
├── POST /{bomId}/obsolete 비활성화
|
||||
├── POST /{bomId}/clone 복제 (새 리비전)
|
||||
├── GET /{bomId}/diff/{otherId} BOM 비교
|
||||
│
|
||||
├── GET /{bomId}/substitutes 대체품목 목록
|
||||
├── POST /{bomId}/lines/{id}/substitutes 대체품목 추가
|
||||
│
|
||||
└── POST /{bomId}/calculate 수식 BOM 계산 (FORMULA 타입)
|
||||
|
||||
/api/v2/bom/
|
||||
├── GET /settings 테넌트 BOM 설정 조회
|
||||
├── PUT /settings 테넌트 BOM 설정 변경
|
||||
├── GET /search BOM 검색 (품목코드, 구성품 등)
|
||||
└── POST /mass-replace 품목 일괄 대체 (ECN)
|
||||
```
|
||||
|
||||
### 9.2 BOM 트리 응답 (V2)
|
||||
|
||||
```json
|
||||
{
|
||||
"bom_header": {
|
||||
"id": 1,
|
||||
"item_id": 100,
|
||||
"revision": "REV.02",
|
||||
"status": "ACTIVE",
|
||||
"bom_type": "STANDARD",
|
||||
"effective_from": "2026-07-01",
|
||||
"base_qty": 1
|
||||
},
|
||||
"tree": {
|
||||
"id": 100,
|
||||
"code": "FG-KSS02",
|
||||
"name": "KSS02 스크린 SUS 측면형",
|
||||
"item_type": "FG",
|
||||
"depth": 0,
|
||||
"children": [
|
||||
{
|
||||
"bom_line_id": 10,
|
||||
"id": 0,
|
||||
"name": "주자재",
|
||||
"item_type": "PH",
|
||||
"is_phantom": true,
|
||||
"depth": 1,
|
||||
"children": [
|
||||
{
|
||||
"bom_line_id": 11,
|
||||
"id": 201,
|
||||
"code": "RM-슬랫-방화",
|
||||
"name": "스크린 실리카",
|
||||
"item_type": "RM",
|
||||
"quantity": 10.65,
|
||||
"unit": "m²",
|
||||
"waste_rate": 0.05,
|
||||
"effective_quantity": 11.18,
|
||||
"operation": { "sequence": 10, "name": "원단 재단" },
|
||||
"substitutes": [
|
||||
{ "item_code": "RM-슬랫-일반", "priority": 1, "factor": 1.0 }
|
||||
],
|
||||
"depth": 2,
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"total_items": 17,
|
||||
"total_groups": 6,
|
||||
"max_depth": 3,
|
||||
"has_substitutes": true,
|
||||
"has_formulas": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. V1 → V2 마이그레이션
|
||||
|
||||
### 10.1 마이그레이션 전략
|
||||
|
||||
```
|
||||
Phase 1: 테이블 생성 (V2 테이블 추가, V1 유지)
|
||||
│
|
||||
Phase 2: 데이터 이관 (items.bom JSON → bom_headers + bom_lines)
|
||||
│
|
||||
Phase 3: API 전환 (V1 API 유지 + V2 API 추가)
|
||||
│
|
||||
Phase 4: 프론트엔드 전환 (MNG/React V2 UI)
|
||||
│
|
||||
Phase 5: V1 폐기 (items.bom 컬럼 제거, V1 API 제거)
|
||||
```
|
||||
|
||||
### 10.2 데이터 이관 스크립트
|
||||
|
||||
```php
|
||||
// items.bom JSON → bom_headers + bom_lines 변환
|
||||
foreach (Item::whereNotNull('bom')->cursor() as $item) {
|
||||
$header = BomHeader::create([
|
||||
'tenant_id' => $item->tenant_id,
|
||||
'item_id' => $item->id,
|
||||
'revision' => 'REV.01',
|
||||
'bom_type' => 'STANDARD',
|
||||
'status' => 'ACTIVE',
|
||||
'base_qty' => 1,
|
||||
]);
|
||||
|
||||
foreach ($item->bom as $i => $bomLine) {
|
||||
BomLine::create([
|
||||
'tenant_id' => $item->tenant_id,
|
||||
'bom_header_id' => $header->id,
|
||||
'child_item_id' => $bomLine['child_item_id'],
|
||||
'quantity' => $bomLine['quantity'] ?? 1,
|
||||
'unit' => $bomLine['unit'] ?? null,
|
||||
'category' => $bomLine['category'] ?? null,
|
||||
'sort_order' => $i,
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 10.3 하위 호환
|
||||
|
||||
| V1 API | V2 대응 | 전환 방식 |
|
||||
|--------|---------|---------|
|
||||
| `GET /v1/items/{id}/bom/tree` | `GET /v2/items/{id}/bom/{activeId}/tree` | V1 래퍼 → V2 호출 |
|
||||
| `POST /v1/items/{id}/save-bom` | `POST /v2/items/{id}/bom` + lines | V1 래퍼 유지 |
|
||||
| `POST /v1/quotes/calculate/bom` | `POST /v2/items/{id}/bom/{id}/calculate` | V1 래퍼 유지 |
|
||||
|
||||
---
|
||||
|
||||
## 11. 구현 로드맵
|
||||
|
||||
### Phase 1: 기반 구축 (2~3주)
|
||||
|
||||
- [ ] `bom_headers`, `bom_lines`, `bom_substitutes` 마이그레이션 생성
|
||||
- [ ] `tenant_bom_settings` 테이블 및 프리셋
|
||||
- [ ] `BomHeader`, `BomLine`, `BomSubstitute` 모델 생성
|
||||
- [ ] `BomService` 핵심 CRUD (생성, 조회, 수정, 삭제)
|
||||
- [ ] V1 items.bom → V2 데이터 이관 스크립트
|
||||
- [ ] V2 BOM API 기본 엔드포인트
|
||||
|
||||
### Phase 2: 핵심 기능 (2~3주)
|
||||
|
||||
- [ ] BOM 트리 빌더 (재귀, 팬텀 투과, 깊이 제한)
|
||||
- [ ] BOM 전개 (Explosion) — 평탄화 조회
|
||||
- [ ] 역전개 (Where-Used) — 이 부품을 사용하는 상위 BOM
|
||||
- [ ] BOM 버전 관리 (리비전 생성, 복제)
|
||||
- [ ] BOM 비교 (Diff)
|
||||
- [ ] items.item_type 확장 (SA, WIP, PH, BP, SV)
|
||||
|
||||
### Phase 3: 확장 기능 (3~4주)
|
||||
|
||||
- [ ] 수식 BOM (FORMULA) — Design BOM 연동 개선
|
||||
- [ ] 대체품목 관리
|
||||
- [ ] 유효기간(Effectivity) 관리
|
||||
- [ ] 공정(Routing) 테이블 및 BOM-공정 연동
|
||||
- [ ] BOM 승인 워크플로우
|
||||
- [ ] 원가 계산 연동 (BOM 기반 표준원가)
|
||||
|
||||
### Phase 4: UI 및 통합 (2~3주)
|
||||
|
||||
- [ ] MNG BOM 관리 UI 전환 (V2 API)
|
||||
- [ ] React BOM 트리 뷰어 V2 연동
|
||||
- [ ] 테넌트 BOM 설정 관리 화면
|
||||
- [ ] V1 API 래퍼 → V2 전환 완료
|
||||
- [ ] V1 items.bom 컬럼 제거
|
||||
|
||||
---
|
||||
|
||||
## 12. 업종별 시나리오 검증
|
||||
|
||||
### 12.1 블라인드/스크린 (현재)
|
||||
|
||||
```
|
||||
설정: STANDARD + FORMULA, WIP 사용, 카테고리 FOLDER
|
||||
검증:
|
||||
✓ 수식 산출 → BOM 자동 생성
|
||||
✓ 절곡품(WIP) BOM 트리
|
||||
✓ 카테고리 그룹 표시
|
||||
✓ V1 데이터 100% 호환
|
||||
```
|
||||
|
||||
### 12.2 전자부품 제조
|
||||
|
||||
```
|
||||
설정: STANDARD + ENGINEERING, SA/PH 사용, 승인 필수, 대체품목, ECN
|
||||
검증:
|
||||
✓ 15단계 BOM 깊이
|
||||
✓ 팬텀 품목 투과 전개
|
||||
✓ ECN 시 일괄 품목 대체
|
||||
✓ 리비전별 유효기간 관리
|
||||
```
|
||||
|
||||
### 12.3 식품 제조
|
||||
|
||||
```
|
||||
설정: FORMULA, 수율 관리, 부산물(BP)
|
||||
검증:
|
||||
✓ 배합비 수식 (A원료 30% + B원료 70%)
|
||||
✓ 로스율 반영 투입량
|
||||
✓ 부산물 자동 등록
|
||||
```
|
||||
|
||||
### 12.4 가구 주문제작
|
||||
|
||||
```
|
||||
설정: CONFIGURABLE, 옵션 조합
|
||||
검증:
|
||||
✓ 상판/다리/마감 옵션별 BOM 분기
|
||||
✓ 주문 시 옵션 선택 → BOM 확정
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
| 문서 | 경로 |
|
||||
|------|------|
|
||||
| 품목 정책 | `rules/item-policy.md` |
|
||||
| 견적 시스템 | `features/quotes/README.md` |
|
||||
| 제품/품목/설계 DB | `system/database/products.md` |
|
||||
| BOM 아이템 매핑 | `dev/dev_plans/bom-item-mapping-plan.md` |
|
||||
| BOM 트리 3단계 | `changes/20260318_item-management-bom-tree.md` |
|
||||
| 재공품 생산 정책 | `rules/wip-production-policy.md` |
|
||||
| options JSON 정책 | `standards/options-column-policy.md` |
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-03-22
|
||||
Reference in New Issue
Block a user