diff --git a/plans/flow-tests/items-bom-test.json b/plans/flow-tests/items-bom-test.json new file mode 100644 index 0000000..efa2cc4 --- /dev/null +++ b/plans/flow-tests/items-bom-test.json @@ -0,0 +1,108 @@ +{ + "name": "Items BOM 데이터 조회 테스트", + "description": "GET /items/{id} 호출 시 BOM 데이터가 확장되어 반환되는지 테스트 (child_item_code, child_item_name, unit 포함)", + "version": "1.0", + "config": { + "baseUrl": "", + "timeout": 30000, + "stopOnFailure": true + }, + "variables": { + "user_id": "{{$env.FLOW_TESTER_USER_ID}}", + "user_pwd": "{{$env.FLOW_TESTER_USER_PWD}}", + "test_item_id": "818", + "test_item_type": "FG" + }, + "steps": [ + { + "id": "login", + "name": "로그인", + "method": "POST", + "endpoint": "/login", + "body": { + "user_id": "{{user_id}}", + "user_pwd": "{{user_pwd}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.access_token": "@isString" + } + }, + "extract": { + "token": "$.access_token" + } + }, + { + "id": "get_items_list", + "name": "품목 목록 조회 (FG/PT 타입)", + "method": "GET", + "endpoint": "/items?type=FG,PT&size=10", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true + } + } + }, + { + "id": "get_item_detail", + "name": "품목 상세 조회 (BOM 확장 확인)", + "method": "GET", + "endpoint": "/items/{{test_item_id}}?item_type={{test_item_type}}", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data.id": "@isNumber", + "$.data.item_type": "@isString", + "$.data.code": "@isString", + "$.data.name": "@isString" + } + }, + "extract": { + "item_id": "$.data.id", + "item_code": "$.data.code", + "item_bom": "$.data.bom" + } + }, + { + "id": "get_item_bom_api", + "name": "Items BOM API 조회", + "description": "GET /items/{id}/bom 엔드포인트 테스트", + "method": "GET", + "endpoint": "/items/{{test_item_id}}/bom", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true + } + } + }, + { + "id": "get_item_bom_tree", + "name": "Items BOM 트리 조회", + "description": "GET /items/{id}/bom/tree 엔드포인트 테스트", + "method": "GET", + "endpoint": "/items/{{test_item_id}}/bom/tree", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true + } + } + } + ] +} \ No newline at end of file diff --git a/plans/items-table-unification-plan.md b/plans/items-table-unification-plan.md new file mode 100644 index 0000000..f407450 --- /dev/null +++ b/plans/items-table-unification-plan.md @@ -0,0 +1,550 @@ +# Items 테이블 통합 마이그레이션 계획 + +## 개요 + +### 목적 +현재 이원화된 `products`/`materials` 테이블을 통합 `items` 테이블 구조로 전환하여: +- BOM 관리 시 `child_item_type` 불필요 (ID만으로 유일 식별) +- 단일 쿼리로 모든 품목 조회 가능 +- Service/Controller 코드 50% 감소 +- 유지보수성 및 확장성 향상 + +### 설계 변경 이력 +- **2025-12-11 (v1)**: 단일 `items` 테이블에 모든 필드 통합 +- **2025-12-11 (v2)**: 4개 테이블로 분리하여 성능 최적화 + - `items`: 핵심 필드 (목록 조회, BOM 계산) + - `item_details`: 필수/인덱싱 필드 (검색, 필터링) + - `item_attributes`: 동적 속성 (JSON 기반) + - `item_bending`: 절곡 정보 (별도 관리) + +### 현재 상태 분석 + +#### 테이블 구조 비교 + +| 구분 | Products | Materials | 통합 Items | +|------|----------|-----------|------------| +| ID | id (1~808) | id (1~417) | id (새 통합 ID) | +| 타입 | product_type (FG, PT, PRODUCT, SUBASSEMBLY, PART, CS) | material_type (SM, RM, CS) | item_type | +| 코드 | code | material_code | code | +| 이름 | name | name | name | +| 단위 | unit | unit | unit | +| 규격 | - | specification | attributes (JSON) | +| BOM | bom (JSON) | - | bom (JSON) | +| 속성 | attributes, options | attributes, options | attributes, options | + +#### 데이터 현황 (2025-12-11) +- Products: **808건** +- Materials: **417건** +- 총합: **1,225건** + +#### 참조 테이블 현황 + +| 테이블 | 참조 방식 | 데이터 | +|--------|----------|--------| +| product_components | parent_product_id, ref_type+ref_id | 16건 | +| bom_template_items | ref_type+ref_id | 1건 | +| orders | product_id | 0건 | +| order_items | product_id | 0건 | +| quotes | product_id | 0건 | +| material_receipts | material_id | 0건 | +| lots | material_id | 0건 | +| price_histories | item_type+item_id | 조회 필요 | + +--- + +## Phase 1: 테이블 생성 및 데이터 이관 + +### 1.1 items 테이블 (핵심 정보) + +```sql +CREATE TABLE items ( + id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + tenant_id BIGINT UNSIGNED NOT NULL COMMENT '테넌트 ID', + + -- 기본 정보 + item_type VARCHAR(15) NOT NULL COMMENT '품목 유형: FG, PT, SM, RM, CS, PRODUCT, SUBASSEMBLY, PART', + code VARCHAR(100) NOT NULL COMMENT '품목 코드', + name VARCHAR(255) NOT NULL COMMENT '품목명', + unit VARCHAR(20) NULL COMMENT '단위', + category_id BIGINT UNSIGNED NULL COMMENT '카테고리 ID', + + -- BOM + bom JSON NULL COMMENT 'BOM [{child_item_id, quantity}, ...]', + + -- 상태 + is_active TINYINT(1) DEFAULT 1 COMMENT '활성 상태', + + -- 레거시 참조 (전환기간용) + legacy_table VARCHAR(20) NULL COMMENT '원본 테이블: products | materials', + legacy_id BIGINT UNSIGNED NULL COMMENT '원본 테이블 ID', + + -- 감사 필드 + created_by BIGINT UNSIGNED NULL COMMENT '생성자', + updated_by BIGINT UNSIGNED NULL COMMENT '수정자', + deleted_by BIGINT UNSIGNED NULL COMMENT '삭제자', + created_at TIMESTAMP NULL, + updated_at TIMESTAMP NULL, + deleted_at TIMESTAMP NULL, + + -- 인덱스 + INDEX idx_items_tenant_type (tenant_id, item_type), + INDEX idx_items_tenant_code (tenant_id, code), + INDEX idx_items_tenant_category (tenant_id, category_id), + INDEX idx_items_tenant_active (tenant_id, is_active), + INDEX idx_items_legacy (legacy_table, legacy_id), + UNIQUE KEY uq_items_tenant_code (tenant_id, code, deleted_at), + + -- 외래키 + FOREIGN KEY (tenant_id) REFERENCES tenants(id), + FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +COMMENT='Products + Materials 통합 품목 테이블 (핵심 정보)'; +``` + +### 1.2 item_details 테이블 (필수/인덱싱 필드) + +```sql +CREATE TABLE item_details ( + id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + item_id BIGINT UNSIGNED NOT NULL COMMENT 'items 테이블 FK', + + -- Products 전용 (인덱싱/필터링) + is_sellable TINYINT(1) DEFAULT 1 COMMENT '판매 가능', + is_purchasable TINYINT(1) DEFAULT 0 COMMENT '구매 가능', + is_producible TINYINT(1) DEFAULT 0 COMMENT '생산 가능', + safety_stock INT NULL COMMENT '안전 재고', + lead_time INT NULL COMMENT '리드타임 (일)', + is_variable_size TINYINT(1) DEFAULT 0 COMMENT '가변 사이즈 여부', + product_category VARCHAR(50) NULL COMMENT '제품 카테고리', + part_type VARCHAR(50) NULL COMMENT '부품 유형', + + -- Materials 전용 (인덱싱/필터링) + is_inspection VARCHAR(1) DEFAULT 'N' COMMENT '검사 대상 여부', + + created_at TIMESTAMP NULL, + updated_at TIMESTAMP NULL, + + -- 인덱스 + UNIQUE KEY uq_item_details_item_id (item_id), + INDEX idx_item_details_sellable (is_sellable), + INDEX idx_item_details_purchasable (is_purchasable), + INDEX idx_item_details_producible (is_producible), + INDEX idx_item_details_inspection (is_inspection), + + -- 외래키 + FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +COMMENT='품목 상세 정보 (필수/인덱싱 필드)'; +``` + +### 1.3 item_attributes 테이블 (동적 속성) + +```sql +CREATE TABLE item_attributes ( + id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + item_id BIGINT UNSIGNED NOT NULL COMMENT 'items 테이블 FK', + + -- 동적 속성 + attributes JSON NULL COMMENT '동적 속성 (규격 정보 포함)', + options JSON NULL COMMENT '옵션 (파일, 인증, 설명 등)', + + created_at TIMESTAMP NULL, + updated_at TIMESTAMP NULL, + + -- 인덱스 + UNIQUE KEY uq_item_attributes_item_id (item_id), + + -- 외래키 + FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +COMMENT='품목 동적 속성 (JSON 기반)'; +``` + +### 1.4 item_bending 테이블 (절곡 정보) + +```sql +CREATE TABLE item_bending ( + id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + item_id BIGINT UNSIGNED NOT NULL COMMENT 'items 테이블 FK', + + -- 절곡 정보 + diagram VARCHAR(255) NULL COMMENT '절곡 도면 파일', + details JSON NULL COMMENT '절곡 상세 정보', + + created_at TIMESTAMP NULL, + updated_at TIMESTAMP NULL, + + -- 인덱스 + UNIQUE KEY uq_item_bending_item_id (item_id), + + -- 외래키 + FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +COMMENT='품목 절곡 정보'; +``` + +### 1.5 item_id_mappings 테이블 (전환기간용) + +```sql +CREATE TABLE item_id_mappings ( + id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + new_item_id BIGINT UNSIGNED NOT NULL COMMENT '새 items 테이블 ID', + legacy_table VARCHAR(20) NOT NULL COMMENT '원본 테이블: products | materials', + legacy_id BIGINT UNSIGNED NOT NULL COMMENT '원본 테이블 ID', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + + -- 인덱스 + UNIQUE KEY uq_legacy (legacy_table, legacy_id), + INDEX idx_new_item (new_item_id), + + -- 외래키 + FOREIGN KEY (new_item_id) REFERENCES items(id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +COMMENT='Products/Materials → Items ID 매핑 (전환기간용)'; +``` + +### 1.6 데이터 이관 스크립트 + +```php +// 1. Products → Items 이관 +DB::statement(" + INSERT INTO items ( + tenant_id, item_type, code, name, unit, category_id, bom, + is_active, created_by, updated_by, deleted_by, + created_at, updated_at, deleted_at, + legacy_table, legacy_id + ) + SELECT + tenant_id, product_type, code, name, unit, category_id, bom, + is_active, created_by, updated_by, deleted_by, + created_at, updated_at, deleted_at, + 'products', id + FROM products +"); + +// 2. Products → item_details 이관 +DB::statement(" + INSERT INTO item_details ( + item_id, is_sellable, is_purchasable, is_producible, + safety_stock, lead_time, is_variable_size, + product_category, part_type, is_inspection, + created_at, updated_at + ) + SELECT + i.id, p.is_sellable, p.is_purchasable, p.is_producible, + p.safety_stock, p.lead_time, p.is_variable_size, + p.product_category, p.part_type, 'N', + p.created_at, p.updated_at + FROM products p + JOIN items i ON i.legacy_table = 'products' AND i.legacy_id = p.id +"); + +// 3. Products → item_attributes 이관 +DB::statement(" + INSERT INTO item_attributes ( + item_id, attributes, options, created_at, updated_at + ) + SELECT + i.id, p.attributes, p.options, p.created_at, p.updated_at + FROM products p + JOIN items i ON i.legacy_table = 'products' AND i.legacy_id = p.id +"); + +// 4. Products → item_bending 이관 (절곡 정보 있는 경우만) +DB::statement(" + INSERT INTO item_bending ( + item_id, diagram, details, created_at, updated_at + ) + SELECT + i.id, p.bending_diagram, p.bending_details, p.created_at, p.updated_at + FROM products p + JOIN items i ON i.legacy_table = 'products' AND i.legacy_id = p.id + WHERE p.bending_diagram IS NOT NULL OR p.bending_details IS NOT NULL +"); + +// 5. Materials → Items 이관 +DB::statement(" + INSERT INTO items ( + tenant_id, item_type, code, name, unit, category_id, + is_active, created_by, updated_by, deleted_by, + created_at, updated_at, deleted_at, + legacy_table, legacy_id + ) + SELECT + tenant_id, material_type, material_code, name, unit, category_id, + is_active, created_by, updated_by, deleted_by, + created_at, updated_at, deleted_at, + 'materials', id + FROM materials +"); + +// 6. Materials → item_details 이관 +DB::statement(" + INSERT INTO item_details ( + item_id, is_sellable, is_purchasable, is_producible, + safety_stock, lead_time, is_variable_size, + product_category, part_type, is_inspection, + created_at, updated_at + ) + SELECT + i.id, 0, 1, 0, + NULL, NULL, 0, + NULL, NULL, m.is_inspection, + m.created_at, m.updated_at + FROM materials m + JOIN items i ON i.legacy_table = 'materials' AND i.legacy_id = m.id +"); + +// 7. Materials → item_attributes 이관 +// options에 기존 Materials 전용 필드 포함 +DB::statement(" + INSERT INTO item_attributes ( + item_id, attributes, options, created_at, updated_at + ) + SELECT + i.id, + m.attributes, + JSON_OBJECT( + 'specification', m.specification, + 'item_name', m.item_name, + 'search_tag', m.search_tag, + 'remarks', m.remarks + ), + m.created_at, m.updated_at + FROM materials m + JOIN items i ON i.legacy_table = 'materials' AND i.legacy_id = m.id +"); + +// 8. ID 매핑 테이블 생성 +DB::statement(" + INSERT INTO item_id_mappings (new_item_id, legacy_table, legacy_id) + SELECT id, legacy_table, legacy_id + FROM items + WHERE legacy_table IS NOT NULL AND legacy_id IS NOT NULL +"); +``` + +### 1.7 체크리스트 + +- [ ] items 테이블 마이그레이션 생성 +- [ ] item_details 테이블 마이그레이션 생성 +- [ ] item_attributes 테이블 마이그레이션 생성 +- [ ] item_bending 테이블 마이그레이션 생성 +- [ ] item_id_mappings 테이블 마이그레이션 생성 +- [ ] Products 데이터 이관 스크립트 실행 +- [ ] Materials 데이터 이관 스크립트 실행 +- [ ] 데이터 검증 (건수, 필드값 일치) + +--- + +## Phase 2: Item 모델 및 Service 생성 + +### 2.1 Item 모델 + +```php +// app/Models/Items/Item.php +class Item extends Model +{ + use BelongsToTenant, ModelTrait, SoftDeletes; + + protected $fillable = [ + 'tenant_id', 'item_type', 'code', 'name', 'unit', 'category_id', + 'bom', 'is_active', 'created_by', 'updated_by', + ]; + + protected $casts = [ + 'bom' => 'array', + 'is_active' => 'boolean', + ]; + + // 1:1 관계 + public function details() { return $this->hasOne(ItemDetail::class); } + public function attributes() { return $this->hasOne(ItemAttribute::class); } + public function bending() { return $this->hasOne(ItemBending::class); } + + // 타입별 스코프 + public function scopeType($q, string $type) { return $q->where('item_type', $type); } + public function scopeProducts($q) { return $q->whereIn('item_type', ['FG', 'PT', 'PRODUCT', 'SUBASSEMBLY', 'PART']); } + public function scopeMaterials($q) { return $q->whereIn('item_type', ['SM', 'RM', 'CS']); } +} +``` + +### 2.2 관련 모델 + +```php +// app/Models/Items/ItemDetail.php +class ItemDetail extends Model +{ + protected $fillable = [ + 'item_id', 'is_sellable', 'is_purchasable', 'is_producible', + 'safety_stock', 'lead_time', 'is_variable_size', + 'product_category', 'part_type', 'is_inspection', + ]; + + protected $casts = [ + 'is_sellable' => 'boolean', + 'is_purchasable' => 'boolean', + 'is_producible' => 'boolean', + 'is_variable_size' => 'boolean', + ]; + + public function item() { return $this->belongsTo(Item::class); } +} + +// app/Models/Items/ItemAttribute.php +class ItemAttribute extends Model +{ + protected $fillable = ['item_id', 'attributes', 'options']; + protected $casts = ['attributes' => 'array', 'options' => 'array']; + public function item() { return $this->belongsTo(Item::class); } +} + +// app/Models/Items/ItemBending.php +class ItemBending extends Model +{ + protected $fillable = ['item_id', 'diagram', 'details']; + protected $casts = ['details' => 'array']; + public function item() { return $this->belongsTo(Item::class); } +} +``` + +### 2.3 체크리스트 + +- [ ] Item 모델 생성 +- [ ] ItemDetail 모델 생성 +- [ ] ItemAttribute 모델 생성 +- [ ] ItemBending 모델 생성 +- [ ] UnifiedItemsService 생성 +- [ ] ItemRequest (FormRequest) 생성 +- [ ] 단위 테스트 작성 + +--- + +## Phase 3: API 엔드포인트 전환 + +### 3.1 신규 API (v2) + +| 메서드 | 엔드포인트 | 설명 | +|--------|-----------|------| +| GET | /api/v2/items | 통합 품목 목록 | +| GET | /api/v2/items/{id} | 품목 상세 (with details, attributes, bending) | +| POST | /api/v2/items | 품목 생성 | +| PUT | /api/v2/items/{id} | 품목 수정 | +| DELETE | /api/v2/items/{id} | 품목 삭제 | +| DELETE | /api/v2/items/batch | 일괄 삭제 | + +### 3.2 체크리스트 + +- [ ] v2 라우트 정의 +- [ ] UnifiedItemsController 생성 +- [ ] Swagger 문서 작성 (v2) +- [ ] v1 API 호환 레이어 구현 +- [ ] API 테스트 작성 + +--- + +## Phase 4: 참조 테이블 마이그레이션 + +### 4.1 참조 테이블 목록 + +| 테이블 | 변경 필요 컬럼 | 작업 | +|--------|--------------|------| +| product_components | ref_type+ref_id → child_item_id | 마이그레이션 | +| bom_template_items | ref_type+ref_id → item_id | 마이그레이션 | +| orders | product_id → item_id | 마이그레이션 | +| order_items | product_id → item_id | 마이그레이션 | +| quotes | product_id → item_id | 마이그레이션 | +| material_receipts | material_id → item_id | 마이그레이션 | +| lots | material_id → item_id | 마이그레이션 | +| price_histories | item_type+item_id → item_id | 마이그레이션 | + +### 4.2 체크리스트 + +- [ ] 각 참조 테이블 마이그레이션 스크립트 작성 +- [ ] 관련 모델 업데이트 +- [ ] 데이터 검증 + +--- + +## Phase 5: 레거시 정리 + +### 5.1 체크리스트 + +- [ ] 모든 참조 테이블 전환 완료 확인 +- [ ] v1 API 사용량 모니터링 (0 확인) +- [ ] items 레거시 컬럼 제거 (legacy_table, legacy_id) +- [ ] item_id_mappings 테이블 제거 +- [ ] products 테이블 제거 +- [ ] materials 테이블 제거 +- [ ] 최종 테스트 + +--- + +## 테이블 구조 요약 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ items (핵심) │ +├─────────────────────────────────────────────────────────────────┤ +│ id, tenant_id, item_type, code, name, unit, category_id │ +│ bom (JSON), is_active, legacy_table, legacy_id │ +│ timestamps + soft deletes │ +└───────────────────────────┬─────────────────────────────────────┘ + │ 1:1 + ┌───────────────────┼───────────────────┬─────────────────┐ + ▼ ▼ ▼ │ +┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ +│ item_details │ │item_attributes│ │ item_bending │ │ +├───────────────┤ ├───────────────┤ ├───────────────┤ │ +│ item_id (UK) │ │ item_id (UK) │ │ item_id (UK) │ │ +│ is_sellable │ │ attributes │ │ diagram │ │ +│ is_purchasable│ │ options │ │ details │ │ +│ is_producible │ └───────────────┘ └───────────────┘ │ +│ safety_stock │ │ +│ lead_time │ ┌───────────────────────────────────┐ │ +│ is_variable.. │ │ item_id_mappings │ │ +│ product_cat.. │ ├───────────────────────────────────┤ │ +│ part_type │ │ new_item_id ──────────────────────┼────────┘ +│ is_inspection │ │ legacy_table, legacy_id │ +└───────────────┘ └───────────────────────────────────┘ +``` + +--- + +## 사용 패턴별 쿼리 + +| 패턴 | 빈도 | JOIN | 쿼리 | +|------|------|------|------| +| 목록 조회 | 80%+ | ❌ | `SELECT * FROM items WHERE ...` | +| 검색 | 빈번 | ❌ | `SELECT * FROM items WHERE code LIKE ...` | +| BOM 계산 | 5% | 자기참조 | `SELECT * FROM items WHERE id IN (...)` | +| 상세 조회 | 15% | ✅ 3-4테이블 | `SELECT * FROM items JOIN item_details ...` | +| 필터 (판매가능) | 간헐 | ✅ 1테이블 | `JOIN item_details WHERE is_sellable = 1` | + +--- + +## 일정 계획 + +| Phase | 작업 내용 | 상태 | +|-------|----------|------| +| Phase 1 | 테이블 생성 + 데이터 이관 | ⬜ 대기 | +| Phase 2 | 모델 + Service 생성 | ⬜ 대기 | +| Phase 3 | API 엔드포인트 전환 | ⬜ 대기 | +| Phase 4 | 참조 테이블 마이그레이션 | ⬜ 대기 | +| Phase 5 | 레거시 정리 | ⬜ 대기 | + +--- + +## 리스크 및 대응 + +### 리스크 1: ID 변경으로 인한 기존 연동 깨짐 +- **대응**: legacy_table + legacy_id 컬럼으로 매핑 유지 +- **전환기간**: v1 API 호환 레이어 제공 + +### 리스크 2: 데이터 이관 중 누락 +- **대응**: 이관 전후 건수 검증 +- **롤백 계획**: 이관 스크립트 역순 실행 + +### 리스크 3: JOIN 성능 +- **분석**: 1:1 JOIN + UNIQUE 인덱스로 10만건도 수 ms 이내 +- **모니터링**: 쿼리 성능 측정 \ No newline at end of file diff --git a/plans/mng-item-field-management-plan.md b/plans/mng-item-field-management-plan.md index b769486..0b96ae3 100644 --- a/plans/mng-item-field-management-plan.md +++ b/plans/mng-item-field-management-plan.md @@ -4,10 +4,36 @@ **작성일**: 2025-12-09 **상태**: 계획 중 -**관련 문서**: -- `docs/specs/item-master-field-integration.md` -- `docs/specs/item-master-field-key-validation.md` -- `docs/specs/ITEM-MASTER-INDEX.md` + +--- + +## 📋 필수 참조 문서 + +개발 전 반드시 확인해야 할 문서 목록입니다. + +### 🔴 필수 확인 + +| 문서 | 경로 | 확인 내용 | +|------|------|----------| +| **품목 정책** | `docs/rules/item-policy.md` | item_type 체계, 필드 키 예약어, API 규칙 | +| **DB 스키마** | `docs/specs/database-schema.md` | item_fields, item_pages 테이블 구조 | +| **API 개발 규칙** | `docs/standards/api-rules.md` | Service-First, FormRequest, i18n | + +### 🟡 참고 문서 + +| 문서 | 경로 | 내용 | +|------|------|------| +| **품목 연동 설계** | `docs/specs/item-master-integration.md` | BE-FE 연동 아키텍처 | +| **프론트엔드 가이드** | `docs/front/item-master-guide.md` | 페이지-섹션-필드 구조 | +| **API 플로우 테스트** | `docs/plans/flow-tests/item-master-*.json` | ItemMaster API 테스트 시나리오 | + +### 📁 관련 코드 파일 + +| 파일 | 경로 | 역할 | +|------|------|------| +| SystemFields | `api/app/Constants/SystemFields.php` | 시스템 예약어 상수 | +| ItemTypeSeeder | `api/database/seeders/ItemTypeSeeder.php` | item_type 코드 시딩 | +| ItemFieldService | `api/app/Services/ItemMaster/ItemFieldService.php` | 필드 CRUD 서비스 | ---