Files
sam-docs/history/2025-11/item-master-gap-analysis.md

811 lines
28 KiB
Markdown
Raw Normal View History

# 품목 마스터 API 갭 분석 보고서
**작성일**: 2025-11-20
**분석자**: Claude Code (Sequential Thinking)
**문서 버전**: v1.0
---
## 📋 목차
1. [요약](#요약)
2. [DB 모델 비교 분석](#db-모델-비교-분석)
3. [API 갭 분석](#api-갭-분석)
4. [구현 전략](#구현-전략)
5. [상세 구현 로드맵](#상세-구현-로드맵)
6. [리스크 및 대응 방안](#리스크-및-대응-방안)
---
## 요약
### 핵심 결론
**프론트 요구사항을 그대로 수용하여 신규 시스템 구축 권장**
-**기존 API 영향 없음**: `/v1/item-master/*` 별도 네임스페이스
-**SAM API Rules 완벽 준수**: Multi-tenant, Service-First, FormRequest 등
-**점진적 마이그레이션 가능**: 기존 Products/Materials와 병행 운영
- ⏱️ **예상 개발 기간**: 4-5주
---
## DB 모델 비교 분석
### 1. 현재 DB 구조 (하이브리드 접근)
#### 핵심 테이블
| 테이블 | 모델 | 특징 | 용도 |
|--------|------|------|------|
| `products` | Product | 고정 필드 + attributes JSON | 제품 마스터 |
| `materials` | Material | 고정 필드 + attributes JSON | 자재 마스터 |
| `product_components` | ProductComponent | ref_type (PRODUCT/MATERIAL) | BOM 관계 |
| `categories` | Category | 계층 구조 | 카테고리 분류 |
| `category_fields` | CategoryField | 동적 필드 정의 | 카테고리별 필드 |
#### 특징
- **하이브리드 구조**: 고정 필드(최소화) + JSON attributes(동적 필드)
- **카테고리 기반**: category_id로 분류
- **BOM 통합**: ProductComponent에서 제품/자재 모두 관리
- **Multi-tenant**: BelongsToTenant 적용
- **Soft Delete**: 모든 테이블 적용
### 2. 프론트 제안 DB 구조 (완전 동적 구조)
#### 9개 테이블
| 테이블 | 용도 | 핵심 특징 |
|--------|------|-----------|
| `item_pages` | 품목 유형별 페이지 관리 | item_type (FG/PT/SM/RM/CS) |
| `item_sections` | 섹션 인스턴스 | type (fields/bom), order_no |
| `item_fields` | 필드 인스턴스 | field_type, validation_rules JSON |
| `item_bom_items` | BOM 항목 | item_code, quantity, unit |
| `section_templates` | 섹션 템플릿 | 재사용 가능 템플릿 |
| `item_master_fields` | 마스터 필드 풀 | 필드 라이브러리 |
| `custom_tabs` | 커스텀 탭 | 탭 정의 |
| `tab_columns` | 탭별 컬럼 설정 | columns JSON |
| `unit_options` | 단위 옵션 | 단위 관리 |
#### 특징
- **페이지-섹션-필드 구조**: 3단계 계층
- **메타 프로그래밍**: 완전 동적 UI 생성 지향
- **템플릿 시스템**: 섹션/필드 재사용
- **실시간 저장**: 모든 CUD 즉시 처리
- **노션 스타일**: 블록 기반 구조
### 3. 구조적 차이점
| 항목 | 현재 구조 | 프론트 제안 |
|------|-----------|-------------|
| **접근 방식** | 하이브리드 (고정+JSON) | 완전 동적 (메타) |
| **분류 체계** | Category 기반 | Page 기반 |
| **필드 정의** | CategoryField | ItemField (인스턴스) |
| **템플릿** | 없음 | SectionTemplate |
| **BOM 구조** | ProductComponent | ItemBomItem |
| **확장성** | 중간 | 매우 높음 |
| **복잡도** | 낮음 | 높음 |
### 4. 재설계 필요 여부
**❌ 기존 구조 확장으로는 불충분**
**이유**:
1. 페이지-섹션-필드 3단계 구조는 기존 카테고리 구조와 근본적으로 다름
2. 섹션 템플릿, 마스터 필드 풀 개념 없음
3. 커스텀 탭 시스템 완전 신규
4. 프론트가 요구하는 메타 프로그래밍 수준 미달
**✅ 신규 시스템 구축 권장**
**근거**:
- 기존 Products/Materials API는 단순 CRUD, 메타 구조 미지원
- 별도 네임스페이스로 구축하여 기존 시스템 영향 없음
- 점진적 마이그레이션 가능 (병행 운영)
---
## API 갭 분석
### 1. 기존 API 현황
#### Products API (`/v1/products/*`)
| 엔드포인트 | 메서드 | 기능 | 재사용 가능성 |
|------------|--------|------|---------------|
| `/v1/products` | GET | 목록 조회 | ❌ 메타 구조 없음 |
| `/v1/products` | POST | 생성 | ❌ 페이지 개념 없음 |
| `/v1/products/{id}` | GET/PATCH/DELETE | 단건 CRUD | ❌ 섹션/필드 미지원 |
| `/v1/products/{id}/bom/items` | GET/POST/PUT | BOM 관리 | 🔶 부분 재사용 가능 |
#### Categories API (`/v1/categories/*`)
| 엔드포인트 | 메서드 | 기능 | 재사용 가능성 |
|------------|--------|------|---------------|
| `/v1/categories` | GET/POST | 목록/생성 | 🔶 템플릿으로 활용 가능 |
| `/v1/categories/{id}/fields` | GET/POST | 필드 관리 | 🔶 마스터 필드로 활용 가능 |
| `/v1/categories/{id}/templates` | GET/POST | 템플릿 | ✅ 부분 재사용 가능 |
#### Items API (`/v1/items/*`)
| 엔드포인트 | 메서드 | 기능 | 재사용 가능성 |
|------------|--------|------|---------------|
| `/v1/items` | GET | 통합 목록 | ❌ 메타 구조 없음 |
| `/v1/items/{code}/bom` | GET/POST | BOM 관리 | 🔶 부분 재사용 가능 |
### 2. 요청 API 목록 (프론트 요구사항)
#### 초기화 API
| 엔드포인트 | 메서드 | 우선순위 | 신규 개발 |
|------------|--------|----------|-----------|
| `GET /v1/item-master/init` | GET | 🔴 필수 | ✅ 완전 신규 |
**특징**: 한 번의 API 호출로 전체 데이터 로드 (pages + sections + fields + bomItems)
#### 페이지 관리 API
| 엔드포인트 | 메서드 | 우선순위 | 신규 개발 |
|------------|--------|----------|-----------|
| `GET /v1/item-master/pages` | GET | 🔴 필수 | ✅ 완전 신규 |
| `POST /v1/item-master/pages` | POST | 🔴 필수 | ✅ 완전 신규 |
| `PUT /v1/item-master/pages/{id}` | PUT | 🔴 필수 | ✅ 완전 신규 |
| `DELETE /v1/item-master/pages/{id}` | DELETE | 🔴 필수 | ✅ 완전 신규 |
#### 섹션 관리 API
| 엔드포인트 | 메서드 | 우선순위 | 신규 개발 |
|------------|--------|----------|-----------|
| `POST /v1/item-master/pages/{pageId}/sections` | POST | 🔴 필수 | ✅ 완전 신규 |
| `PUT /v1/item-master/sections/{id}` | PUT | 🔴 필수 | ✅ 완전 신규 |
| `DELETE /v1/item-master/sections/{id}` | DELETE | 🔴 필수 | ✅ 완전 신규 |
| `PUT /v1/item-master/pages/{pageId}/sections/reorder` | PUT | 🟡 중요 | ✅ 완전 신규 |
#### 필드 관리 API
| 엔드포인트 | 메서드 | 우선순위 | 신규 개발 |
|------------|--------|----------|-----------|
| `POST /v1/item-master/sections/{sectionId}/fields` | POST | 🔴 필수 | ✅ 완전 신규 |
| `PUT /v1/item-master/fields/{id}` | PUT | 🔴 필수 | ✅ 완전 신규 |
| `DELETE /v1/item-master/fields/{id}` | DELETE | 🔴 필수 | ✅ 완전 신규 |
| `PUT /v1/item-master/sections/{sectionId}/fields/reorder` | PUT | 🟡 중요 | ✅ 완전 신규 |
#### BOM 관리 API
| 엔드포인트 | 메서드 | 우선순위 | 신규 개발 |
|------------|--------|----------|-----------|
| `POST /v1/item-master/sections/{sectionId}/bom-items` | POST | 🟡 중요 | ✅ 완전 신규 |
| `PUT /v1/item-master/bom-items/{id}` | PUT | 🟡 중요 | ✅ 완전 신규 |
| `DELETE /v1/item-master/bom-items/{id}` | DELETE | 🟡 중요 | ✅ 완전 신규 |
#### 부가 기능 API
| 엔드포인트 | 메서드 | 우선순위 | 신규 개발 |
|------------|--------|----------|-----------|
| `GET/POST/PUT/DELETE /v1/item-master/section-templates` | ALL | 🟢 부가 | ✅ 완전 신규 |
| `GET/POST/PUT/DELETE /v1/item-master/master-fields` | ALL | 🟢 부가 | ✅ 완전 신규 |
| `GET/POST/PUT/DELETE /v1/item-master/custom-tabs` | ALL | 🟢 부가 | ✅ 완전 신규 |
| `PUT /v1/item-master/custom-tabs/{id}/columns` | PUT | 🟢 부가 | ✅ 완전 신규 |
| `GET/POST/DELETE /v1/item-master/units` | ALL | 🟡 중요 | ✅ 완전 신규 |
### 3. API 갭 요약
**총 요청 API**: 약 35개 엔드포인트
**재사용 가능**: 0개 (완전 신규 개발 필요)
**이유**:
1. 페이지-섹션-필드 구조는 기존 API에 없음
2. 메타 프로그래밍 수준의 동적 구조 미지원
3. 초기화 API처럼 Nested 데이터 로드 패턴 없음
4. 순서 변경(reorder) API 패턴 일부만 존재
---
## 구현 전략
### 1. 권장 접근 방식
**✅ 옵션 C: 병행 운영 (신구 공존)**
```
┌─────────────────────────────────────┐
│ 기존 시스템 (유지) │
│ - /v1/products/* │
│ - /v1/materials/* │
│ - /v1/categories/* │
└─────────────────────────────────────┘
│ (어댑터 레이어)
┌─────────────────────────────────────┐
│ 신규 시스템 (추가) │
│ - /v1/item-master/* │
│ - 완전 동적 메타 구조 │
└─────────────────────────────────────┘
```
**장점**:
- ✅ 기존 API 영향 없음 (별도 네임스페이스)
- ✅ 점진적 마이그레이션 가능
- ✅ 롤백 가능한 구조
- ✅ 프론트 요구사항 완벽 충족
**단점**:
- ⚠️ 중복 데이터 관리 (단기적)
- ⚠️ 동기화 이슈 (선택적 연동)
### 2. SAM API Development Rules 준수
| 규칙 | 적용 방법 | 상태 |
|------|-----------|------|
| **Service-First** | 모든 비즈니스 로직 → Service 클래스 | ✅ 필수 |
| **Multi-tenant** | BelongsToTenant 스코프, tenant_id | ✅ 필수 |
| **Soft Delete** | deleted_at, deleted_by | ✅ 필수 |
| **공통 컬럼** | tenant_id, created_by, updated_by, deleted_by | ✅ 필수 |
| **FormRequest** | Controller 검증 금지 | ✅ 필수 |
| **i18n** | __('message.xxx') 키만 사용 | ✅ 필수 |
| **감사 로그** | audit_logs 기록 | ✅ 필수 |
| **Swagger** | app/Swagger/v1/ItemMasterApi.php | ✅ 필수 |
### 3. 아키텍처 구조
```
┌──────────────────────────────────────────────┐
│ Controller Layer │
│ - ItemPageController │
│ - ItemSectionController │
│ - ItemFieldController (FormRequest 검증) │
└───────────────┬──────────────────────────────┘
┌──────────────────────────────────────────────┐
│ Service Layer │
│ - ItemPageService │
│ - ItemSectionService (비즈니스 로직) │
│ - ItemFieldService │
└───────────────┬──────────────────────────────┘
┌──────────────────────────────────────────────┐
│ Model Layer │
│ - ItemPage (BelongsToTenant) │
│ - ItemSection (SoftDeletes) │
│ - ItemField (ModelTrait) │
└───────────────┬──────────────────────────────┘
┌──────────────────────────────────────────────┐
│ Database Layer │
│ - item_pages (tenant_id, indexes) │
│ - item_sections │
│ - item_fields │
└──────────────────────────────────────────────┘
```
---
## 상세 구현 로드맵
### Week 1: DB 설계 및 마이그레이션 (5일)
#### Day 1-2: 마이그레이션 파일 작성
**순서** (의존성 고려):
```
1. unit_options
2. section_templates
3. item_master_fields
4. item_pages
5. item_sections
6. item_fields
7. item_bom_items
8. custom_tabs
9. tab_columns
```
**각 마이그레이션 포함 사항**:
- ✅ tenant_id BIGINT NOT NULL, INDEX
- ✅ created_by, updated_by, deleted_by
- ✅ created_at, updated_at, deleted_at
- ✅ FK constraints (tenants 테이블)
- ✅ 컬럼 COMMENT 작성
- ✅ INDEX 설정 (tenant_id, order_no 등)
#### Day 3-4: Model 클래스 작성
**app/Models/ItemMaster/** 디렉토리 생성
**각 모델 필수 요소**:
```php
<?php
namespace App\Models\ItemMaster;
use App\Traits\BelongsToTenant;
use App\Traits\ModelTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class ItemPage extends Model
{
use BelongsToTenant, ModelTrait, SoftDeletes;
protected $fillable = [
'tenant_id', 'page_name', 'item_type',
'absolute_path', 'is_active',
'created_by', 'updated_by', 'deleted_by',
];
protected $casts = [
'is_active' => 'boolean',
];
// Relationships
public function sections()
{
return $this->hasMany(ItemSection::class, 'page_id')
->orderBy('order_no');
}
}
```
#### Day 5: 테스트 데이터 시드 작성
**database/seeders/ItemMasterSeeder.php**
- 샘플 페이지 (FG, PT, SM, RM, CS)
- 샘플 섹션 (기본 정보, 치수 정보, BOM)
- 샘플 필드 (제품명, 규격, 수량 등)
- 샘플 템플릿
- 샘플 단위 (kg, EA, m 등)
### Week 2-3: Core API 개발 (10일)
#### 우선순위 1: 필수 API (6일)
**Day 1: 초기화 API**
**파일 생성**:
- `app/Services/ItemMaster/ItemMasterService.php`
- `app/Http/Controllers/Api/V1/ItemMaster/ItemMasterController.php`
**구현 내용**:
```php
// ItemMasterService.php
public function init(): array
{
$pages = ItemPage::with([
'sections.fields',
'sections.bomItems'
])
->where('tenant_id', $this->tenantId())
->where('is_active', true)
->orderBy('id')
->get();
$templates = SectionTemplate::where('tenant_id', $this->tenantId())->get();
$masterFields = ItemMasterField::where('tenant_id', $this->tenantId())->get();
$customTabs = CustomTab::where('tenant_id', $this->tenantId())->orderBy('order_no')->get();
$unitOptions = UnitOption::where('tenant_id', $this->tenantId())->get();
return [
'pages' => $pages,
'sectionTemplates' => $templates,
'masterFields' => $masterFields,
'customTabs' => $customTabs,
'unitOptions' => $unitOptions,
];
}
```
**Day 2-3: 페이지 CRUD**
**파일 생성**:
- `app/Services/ItemMaster/ItemPageService.php`
- `app/Http/Controllers/Api/V1/ItemMaster/ItemPageController.php`
- `app/Http/Requests/ItemMaster/ItemPageStoreRequest.php`
- `app/Http/Requests/ItemMaster/ItemPageUpdateRequest.php`
**구현 메서드**:
- `index()` - 목록 조회 (with sections, fields)
- `store()` - 페이지 생성
- `show()` - 단건 조회
- `update()` - 수정
- `destroy()` - Soft Delete (Cascade)
**Day 4-5: 섹션 CRUD**
**파일 생성**:
- `app/Services/ItemMaster/ItemSectionService.php`
- `app/Http/Controllers/Api/V1/ItemMaster/ItemSectionController.php`
- `app/Http/Requests/ItemMaster/ItemSectionStoreRequest.php`
- `app/Http/Requests/ItemMaster/ItemSectionUpdateRequest.php`
**특수 로직**:
- `order_no` 자동 계산 (해당 페이지의 마지막 섹션 + 1)
- `reorder()` 메서드 (순서 일괄 변경)
**Day 6: 필드 CRUD**
**파일 생성**:
- `app/Services/ItemMaster/ItemFieldService.php`
- `app/Http/Controllers/Api/V1/ItemMaster/ItemFieldController.php`
- `app/Http/Requests/ItemMaster/ItemFieldStoreRequest.php`
- `app/Http/Requests/ItemMaster/ItemFieldUpdateRequest.php`
**JSON 필드 처리**:
- `display_condition` JSON 검증
- `validation_rules` JSON 검증
- `options` JSON 검증
- `properties` JSON 검증
#### 우선순위 2: 중요 API (4일)
**Day 7: BOM 관리**
**파일 생성**:
- `app/Services/ItemMaster/ItemBomService.php`
- `app/Http/Controllers/Api/V1/ItemMaster/ItemBomItemController.php`
- `app/Http/Requests/ItemMaster/ItemBomStoreRequest.php`
- `app/Http/Requests/ItemMaster/ItemBomUpdateRequest.php`
**Day 8: 순서 변경 API**
**구현**:
- 섹션 순서 변경 (`ItemSectionService::reorder()`)
- 필드 순서 변경 (`ItemFieldService::reorder()`)
- 트랜잭션 처리 필수
**Day 9: 단위 관리**
**파일 생성**:
- `app/Services/ItemMaster/UnitOptionService.php`
- `app/Http/Controllers/Api/V1/ItemMaster/UnitOptionController.php`
- `app/Http/Requests/ItemMaster/UnitOptionStoreRequest.php`
**Day 10: 통합 테스트**
- Postman Collection 작성
- 우선순위 1+2 API 전체 테스트
- 버그 수정
### Week 4: 부가 기능 (5일)
#### Day 1-2: 템플릿 관리
**파일 생성**:
- `app/Services/ItemMaster/SectionTemplateService.php`
- `app/Http/Controllers/Api/V1/ItemMaster/SectionTemplateController.php`
- FormRequest 클래스
#### Day 3: 마스터 필드 관리
**파일 생성**:
- `app/Services/ItemMaster/ItemMasterFieldService.php`
- `app/Http/Controllers/Api/V1/ItemMaster/ItemMasterFieldController.php`
- FormRequest 클래스
#### Day 4-5: 커스텀 탭 관리
**파일 생성**:
- `app/Services/ItemMaster/CustomTabService.php`
- `app/Http/Controllers/Api/V1/ItemMaster/CustomTabController.php`
- `app/Http/Requests/ItemMaster/TabColumnUpdateRequest.php`
**특수 기능**:
- 탭 순서 변경 (`reorder()`)
- 컬럼 설정 (`updateColumns()`)
### Week 5: 문서화 및 테스트 (5일)
#### Day 1-2: Swagger 문서화
**파일 생성**: `app/Swagger/v1/ItemMasterApi.php`
**포함 내용**:
```php
<?php
namespace App\Swagger\v1;
/**
* @OA\Tag(
* name="ItemMaster",
* description="품목 기준 관리 API"
* )
*
* @OA\Schema(
* schema="ItemPage",
* type="object",
* required={"page_name", "item_type"},
* @OA\Property(property="id", type="integer"),
* @OA\Property(property="page_name", type="string"),
* @OA\Property(property="item_type", type="string", enum={"FG", "PT", "SM", "RM", "CS"}),
* ...
* )
*/
class ItemMasterApi
{
/**
* @OA\Get(
* path="/api/v1/item-master/init",
* tags={"ItemMaster"},
* summary="초기화 API",
* description="화면 진입 시 전체 데이터 로드",
* security={{"BearerAuth": {}}},
* @OA\Response(
* response=200,
* description="성공",
* @OA\JsonContent(
* @OA\Property(property="success", type="boolean", example=true),
* @OA\Property(property="message", type="string", example="message.fetched"),
* @OA\Property(property="data", type="object",
* @OA\Property(property="pages", type="array", @OA\Items(ref="#/components/schemas/ItemPage")),
* @OA\Property(property="sectionTemplates", type="array", @OA\Items(ref="#/components/schemas/SectionTemplate")),
* ...
* )
* )
* )
* )
*/
public function init() {}
// ... 나머지 엔드포인트
}
```
**Swagger 생성**:
```bash
php artisan l5-swagger:generate
```
#### Day 3: 단위 테스트 작성
**tests/Unit/Services/ItemMaster/**
- `ItemPageServiceTest.php`
- `ItemSectionServiceTest.php`
- `ItemFieldServiceTest.php`
**커버리지 목표**: 80% 이상
#### Day 4: 통합 테스트
**tests/Feature/ItemMaster/**
- `ItemMasterInitTest.php`
- `ItemPageCrudTest.php`
- `ItemSectionCrudTest.php`
#### Day 5: 성능 최적화
**Eager Loading 최적화**:
```php
ItemPage::with([
'sections' => function ($query) {
$query->orderBy('order_no');
},
'sections.fields' => function ($query) {
$query->orderBy('order_no');
},
'sections.bomItems'
])->get();
```
**INDEX 확인**:
- `tenant_id` INDEX
- `(page_id, order_no)` COMPOSITE INDEX
- `(section_id, order_no)` COMPOSITE INDEX
---
## 리스크 및 대응 방안
### 1. 기술적 리스크
| 리스크 | 영향도 | 대응 방안 |
|--------|--------|-----------|
| **Nested 데이터 성능 이슈** | 🟡 중간 | Eager Loading, INDEX 최적화, 페이지네이션 |
| **JSON 필드 검증 복잡도** | 🟡 중간 | FormRequest 규칙 체계화, JSON Schema 활용 |
| **Cascade 삭제 오류** | 🔴 높음 | 트랜잭션 처리, 테스트 케이스 강화 |
| **순서 변경 동시성 이슈** | 🟡 중간 | Lock 메커니즘, 트랜잭션 격리 수준 상향 |
### 2. 일정 리스크
| 리스크 | 영향도 | 대응 방안 |
|--------|--------|-----------|
| **API 개발 지연** | 🟡 중간 | 우선순위별 단계 개발, 최소 기능 먼저 완성 |
| **프론트 연동 지연** | 🟢 낮음 | Swagger 문서 먼저 제공, Mock API 활용 |
| **버그 수정 시간 부족** | 🟡 중간 | Week 5 버퍼 시간 활용 |
### 3. 데이터 리스크
| 리스크 | 영향도 | 대응 방안 |
|--------|--------|-----------|
| **기존 데이터 마이그레이션** | 🟢 낮음 | 선택적 마이그레이션 (필요시) |
| **중복 데이터 동기화** | 🟢 낮음 | 초기에는 병행 운영, 추후 통합 고려 |
### 4. 운영 리스크
| 리스크 | 영향도 | 대응 방안 |
|--------|--------|-----------|
| **API 버전 관리** | 🟢 낮음 | v1 네임스페이스 유지 |
| **감사 로그 볼륨 증가** | 🟡 중간 | 13개월 자동 정리, 아카이빙 전략 |
| **Swagger 문서 유지보수** | 🟢 낮음 | 별도 파일 관리, 자동 생성 |
---
## 부록
### A. 파일 구조
```
api/
├── app/
│ ├── Models/
│ │ └── ItemMaster/
│ │ ├── ItemPage.php
│ │ ├── ItemSection.php
│ │ ├── ItemField.php
│ │ ├── ItemBomItem.php
│ │ ├── SectionTemplate.php
│ │ ├── ItemMasterField.php
│ │ ├── CustomTab.php
│ │ ├── TabColumn.php
│ │ └── UnitOption.php
│ ├── Services/
│ │ └── ItemMaster/
│ │ ├── ItemMasterService.php
│ │ ├── ItemPageService.php
│ │ ├── ItemSectionService.php
│ │ ├── ItemFieldService.php
│ │ ├── ItemBomService.php
│ │ ├── SectionTemplateService.php
│ │ ├── ItemMasterFieldService.php
│ │ ├── CustomTabService.php
│ │ └── UnitOptionService.php
│ ├── Http/
│ │ ├── Controllers/
│ │ │ └── Api/
│ │ │ └── V1/
│ │ │ └── ItemMaster/
│ │ │ ├── ItemMasterController.php
│ │ │ ├── ItemPageController.php
│ │ │ ├── ItemSectionController.php
│ │ │ ├── ItemFieldController.php
│ │ │ ├── ItemBomItemController.php
│ │ │ ├── SectionTemplateController.php
│ │ │ ├── ItemMasterFieldController.php
│ │ │ ├── CustomTabController.php
│ │ │ └── UnitOptionController.php
│ │ └── Requests/
│ │ └── ItemMaster/
│ │ ├── ItemPageStoreRequest.php
│ │ ├── ItemPageUpdateRequest.php
│ │ ├── ItemSectionStoreRequest.php
│ │ ├── ItemSectionUpdateRequest.php
│ │ ├── ItemFieldStoreRequest.php
│ │ ├── ItemFieldUpdateRequest.php
│ │ ├── ItemBomStoreRequest.php
│ │ ├── ItemBomUpdateRequest.php
│ │ ├── SectionTemplateStoreRequest.php
│ │ ├── ItemMasterFieldStoreRequest.php
│ │ ├── CustomTabStoreRequest.php
│ │ ├── TabColumnUpdateRequest.php
│ │ └── UnitOptionStoreRequest.php
│ └── Swagger/
│ └── v1/
│ └── ItemMasterApi.php
├── database/
│ ├── migrations/
│ │ ├── 2025_11_20_100000_create_unit_options_table.php
│ │ ├── 2025_11_20_100001_create_section_templates_table.php
│ │ ├── 2025_11_20_100002_create_item_master_fields_table.php
│ │ ├── 2025_11_20_100003_create_item_pages_table.php
│ │ ├── 2025_11_20_100004_create_item_sections_table.php
│ │ ├── 2025_11_20_100005_create_item_fields_table.php
│ │ ├── 2025_11_20_100006_create_item_bom_items_table.php
│ │ ├── 2025_11_20_100007_create_custom_tabs_table.php
│ │ └── 2025_11_20_100008_create_tab_columns_table.php
│ └── seeders/
│ └── ItemMasterSeeder.php
└── tests/
├── Unit/
│ └── Services/
│ └── ItemMaster/
│ ├── ItemPageServiceTest.php
│ ├── ItemSectionServiceTest.php
│ └── ItemFieldServiceTest.php
└── Feature/
└── ItemMaster/
├── ItemMasterInitTest.php
├── ItemPageCrudTest.php
└── ItemSectionCrudTest.php
```
### B. i18n 메시지 키
**lang/ko/message.php 추가**:
```php
return [
// 기존 키...
// 품목 마스터
'item_master' => [
'fetched' => '품목 기준 정보가 조회되었습니다.',
'page_created' => '페이지가 생성되었습니다.',
'page_updated' => '페이지가 수정되었습니다.',
'page_deleted' => '페이지가 삭제되었습니다.',
'section_created' => '섹션이 생성되었습니다.',
'section_updated' => '섹션이 수정되었습니다.',
'section_deleted' => '섹션이 삭제되었습니다.',
'section_reordered' => '섹션 순서가 변경되었습니다.',
'field_created' => '필드가 생성되었습니다.',
'field_updated' => '필드가 수정되었습니다.',
'field_deleted' => '필드가 삭제되었습니다.',
'field_reordered' => '필드 순서가 변경되었습니다.',
'bom_created' => 'BOM 항목이 생성되었습니다.',
'bom_updated' => 'BOM 항목이 수정되었습니다.',
'bom_deleted' => 'BOM 항목이 삭제되었습니다.',
'template_created' => '템플릿이 생성되었습니다.',
'unit_created' => '단위가 생성되었습니다.',
'unit_deleted' => '단위가 삭제되었습니다.',
'tab_created' => '탭이 생성되었습니다.',
'tab_updated' => '탭이 수정되었습니다.',
'tab_deleted' => '탭이 삭제되었습니다.',
'tab_reordered' => '탭 순서가 변경되었습니다.',
'columns_updated' => '컬럼 설정이 업데이트되었습니다.',
],
];
```
### C. 체크리스트
**개발 완료 전 확인사항**:
```
□ Service-First 패턴 적용 (Controller는 DI + Service 호출만)
□ BelongsToTenant scope 모든 모델에 적용
□ SoftDeletes 모든 모델에 적용
□ 공통 컬럼 (tenant_id, created_by, updated_by, deleted_by) 포함
□ 감사 로그 생성/수정/삭제 시 기록
□ i18n 메시지 키 사용 (__('message.item_master.xxx'))
□ FormRequest 검증
□ Swagger 문서화 (app/Swagger/v1/ItemMasterApi.php)
□ Cascade 삭제 정책 적용
□ Nested 조회 최적화 (Eager Loading)
□ order_no 자동 계산 로직
□ 실시간 저장 지원 (일괄 저장 없음)
□ JSON 필드 검증 (display_condition, validation_rules, options, properties)
□ INDEX 최적화 (tenant_id, order_no 등)
□ 트랜잭션 처리 (reorder, cascade delete)
□ 단위 테스트 80% 이상
□ 통합 테스트 주요 플로우 커버
□ Postman Collection 작성
□ 프론트 연동 테스트 완료
```
---
## 결론
**✅ 프론트 요구사항 수용 → 신규 시스템 구축 권장**
**예상 기간**: 4-5주
**예상 리소스**: 백엔드 개발자 1명 (풀타임)
**리스크 수준**: 🟡 중간 (관리 가능)
**다음 단계**:
1. ✅ 분석 보고서 검토 및 승인
2. 📋 Week 1 마이그레이션 작업 시작
3. 🔧 Core API 개발 착수
**문의 사항**:
- 백엔드 개발팀: [연락처]
- 프론트엔드 개발팀: [연락처]
---
**문서 버전**: v1.0
**작성일**: 2025-11-20
**다음 리뷰 예정일**: DB 마이그레이션 완료 후