- 5130 레거시 시스템 분석 (00_OVERVIEW ~ 08_SAM_COMPARISON) - MES 프로젝트 문서 - API/프론트엔드 스펙 문서 - 가이드 및 레퍼런스 문서
28 KiB
품목 마스터 API 갭 분석 보고서
작성일: 2025-11-20 분석자: Claude Code (Sequential Thinking) 문서 버전: v1.0
📋 목차
요약
핵심 결론
프론트 요구사항을 그대로 수용하여 신규 시스템 구축 권장
- ✅ 기존 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. 재설계 필요 여부
❌ 기존 구조 확장으로는 불충분
이유:
- 페이지-섹션-필드 3단계 구조는 기존 카테고리 구조와 근본적으로 다름
- 섹션 템플릿, 마스터 필드 풀 개념 없음
- 커스텀 탭 시스템 완전 신규
- 프론트가 요구하는 메타 프로그래밍 수준 미달
✅ 신규 시스템 구축 권장
근거:
- 기존 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개 (완전 신규 개발 필요)
이유:
- 페이지-섹션-필드 구조는 기존 API에 없음
- 메타 프로그래밍 수준의 동적 구조 미지원
- 초기화 API처럼 Nested 데이터 로드 패턴 없음
- 순서 변경(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
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.phpapp/Http/Controllers/Api/V1/ItemMaster/ItemMasterController.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.phpapp/Http/Controllers/Api/V1/ItemMaster/ItemPageController.phpapp/Http/Requests/ItemMaster/ItemPageStoreRequest.phpapp/Http/Requests/ItemMaster/ItemPageUpdateRequest.php
구현 메서드:
index()- 목록 조회 (with sections, fields)store()- 페이지 생성show()- 단건 조회update()- 수정destroy()- Soft Delete (Cascade)
Day 4-5: 섹션 CRUD
파일 생성:
app/Services/ItemMaster/ItemSectionService.phpapp/Http/Controllers/Api/V1/ItemMaster/ItemSectionController.phpapp/Http/Requests/ItemMaster/ItemSectionStoreRequest.phpapp/Http/Requests/ItemMaster/ItemSectionUpdateRequest.php
특수 로직:
order_no자동 계산 (해당 페이지의 마지막 섹션 + 1)reorder()메서드 (순서 일괄 변경)
Day 6: 필드 CRUD
파일 생성:
app/Services/ItemMaster/ItemFieldService.phpapp/Http/Controllers/Api/V1/ItemMaster/ItemFieldController.phpapp/Http/Requests/ItemMaster/ItemFieldStoreRequest.phpapp/Http/Requests/ItemMaster/ItemFieldUpdateRequest.php
JSON 필드 처리:
display_conditionJSON 검증validation_rulesJSON 검증optionsJSON 검증propertiesJSON 검증
우선순위 2: 중요 API (4일)
Day 7: BOM 관리
파일 생성:
app/Services/ItemMaster/ItemBomService.phpapp/Http/Controllers/Api/V1/ItemMaster/ItemBomItemController.phpapp/Http/Requests/ItemMaster/ItemBomStoreRequest.phpapp/Http/Requests/ItemMaster/ItemBomUpdateRequest.php
Day 8: 순서 변경 API
구현:
- 섹션 순서 변경 (
ItemSectionService::reorder()) - 필드 순서 변경 (
ItemFieldService::reorder()) - 트랜잭션 처리 필수
Day 9: 단위 관리
파일 생성:
app/Services/ItemMaster/UnitOptionService.phpapp/Http/Controllers/Api/V1/ItemMaster/UnitOptionController.phpapp/Http/Requests/ItemMaster/UnitOptionStoreRequest.php
Day 10: 통합 테스트
- Postman Collection 작성
- 우선순위 1+2 API 전체 테스트
- 버그 수정
Week 4: 부가 기능 (5일)
Day 1-2: 템플릿 관리
파일 생성:
app/Services/ItemMaster/SectionTemplateService.phpapp/Http/Controllers/Api/V1/ItemMaster/SectionTemplateController.php- FormRequest 클래스
Day 3: 마스터 필드 관리
파일 생성:
app/Services/ItemMaster/ItemMasterFieldService.phpapp/Http/Controllers/Api/V1/ItemMaster/ItemMasterFieldController.php- FormRequest 클래스
Day 4-5: 커스텀 탭 관리
파일 생성:
app/Services/ItemMaster/CustomTabService.phpapp/Http/Controllers/Api/V1/ItemMaster/CustomTabController.phpapp/Http/Requests/ItemMaster/TabColumnUpdateRequest.php
특수 기능:
- 탭 순서 변경 (
reorder()) - 컬럼 설정 (
updateColumns())
Week 5: 문서화 및 테스트 (5일)
Day 1-2: Swagger 문서화
파일 생성: app/Swagger/v1/ItemMasterApi.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 생성:
php artisan l5-swagger:generate
Day 3: 단위 테스트 작성
tests/Unit/Services/ItemMaster/
ItemPageServiceTest.phpItemSectionServiceTest.phpItemFieldServiceTest.php
커버리지 목표: 80% 이상
Day 4: 통합 테스트
tests/Feature/ItemMaster/
ItemMasterInitTest.phpItemPageCrudTest.phpItemSectionCrudTest.php
Day 5: 성능 최적화
Eager Loading 최적화:
ItemPage::with([
'sections' => function ($query) {
$query->orderBy('order_no');
},
'sections.fields' => function ($query) {
$query->orderBy('order_no');
},
'sections.bomItems'
])->get();
INDEX 확인:
tenant_idINDEX(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 추가:
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명 (풀타임) 리스크 수준: 🟡 중간 (관리 가능)
다음 단계:
- ✅ 분석 보고서 검토 및 승인
- 📋 Week 1 마이그레이션 작업 시작
- 🔧 Core API 개발 착수
문의 사항:
- 백엔드 개발팀: [연락처]
- 프론트엔드 개발팀: [연락처]
문서 버전: v1.0 작성일: 2025-11-20 다음 리뷰 예정일: DB 마이그레이션 완료 후