---
source: Phase 0 + 프론트엔드 가이드 통합 분석
section: BP-MES 백엔드 개발 로드맵 (개정판)
created: 2025-11-13
updated: 2025-11-13
bp_mes_phase: Phase 0 완료, Phase 1 준비
related:
  - ITEM_MANAGEMENT_MIGRATION_GUIDE.md (프론트엔드 가이드)
  - PHASE_0_FINAL_REPORT.md
  - api_gap_validation_report.md
tags: [backend, roadmap, api, database, laravel]
---

# BP-MES 백엔드 개발 로드맵 V2

**작성일:** 2025-11-13
**기반:** Next.js 15 프론트엔드 가이드 + Phase 0 분석
**대상:** 백엔드 개발자 (프론트엔드 작업 제외)
**프레임워크:** Laravel 12 + PHP 8.2+

---

## 📋 Executive Summary

### 변경 사항
- ✅ **프론트엔드 가이드 통합:** Next.js 15 마이그레이션 가이드 기반 API 요구사항 반영
- ✅ **우선순위 재조정:** 프론트엔드 80% 물리적 페이지 → 백엔드 고정 필드 우선
- ✅ **선택적 확장:** 동적 템플릿 시스템 2차 목표로 후순위
- ⚠️ **프론트엔드 작업 제외:** 백엔드 API 개발에만 집중

### 핵심 방향
1. **하이브리드 전략:** 고정 필드 API (우선) + 메타데이터 API (선택)
2. **RESTful 설계:** 프론트 가이드 엔드포인트 스펙 준수
3. **BOM 계산 강화:** quantityFormula, 계층 구조, tree API
4. **파일 관리:** 절곡도, 시방서, 인정서 업로드

---

## 🎯 프론트엔드 요구사항 분석

### 1. 데이터 구조 (프론트엔드 가이드 기준)

#### 1.1 ItemMaster 필드 구성

**공통 필드 (ALL):**
```
필수:
- id, itemCode, itemName, itemType, unit
- specification, isActive

분류:
- category1, category2, category3

가격:
- purchasePrice, salesPrice, marginRate
- processingCost, laborCost, installCost

BOM:
- bom[] (BOMLine 배열)
- bomCategories[]

메타:
- safetyStock, leadTime, isVariableSize
- revisions[]
- createdAt, updatedAt
```

**FG (제품) 전용:**
```
- productCategory: 'SCREEN' | 'STEEL'
- lotAbbreviation: string (예: "KD")
- note: string
```

**PT (부품) 전용:**
```
기본:
- partType: 'ASSEMBLY' | 'BENDING' | 'PURCHASED'
- partUsage: 'GUIDE_RAIL' | 'BOTTOM_FINISH' | 'CASE' | 'DOOR' | 'BRACKET' | 'GENERAL'

조립 부품:
- installationType, assemblyType
- sideSpecWidth, sideSpecHeight, assemblyLength
- guideRailModelType, guideRailModel (가이드레일)

절곡품:
- bendingDiagram: string (이미지 URL)
- bendingDetails: BendingDetail[] (전개도 데이터)
- material, length, bendingLength
```

**인증 정보 (FG/PT):**
```
- certificationNumber
- certificationStartDate, certificationEndDate
- specificationFile, specificationFileName
- certificationFile, certificationFileName
```

---

#### 1.2 BOMLine 구조

```
필수:
- id, childItemCode, childItemName
- quantity, unit, unitPrice
- note

핵심:
- quantityFormula: string  // 🔴 "W * 2", "H + 100", "G/1000*1.02"

절곡품:
- isBending: boolean
- bendingDiagram: string
- bendingDetails: BendingDetail[]
```

**백엔드 요구:**
- ✅ quantityFormula 저장 (text 컬럼)
- ✅ 계산 로직 (수식 파싱 및 실행)

---

#### 1.3 BendingDetail 구조

```typescript
{
  id: string
  no: number           // 순서
  input: number        // 입력값
  elongation: number   // 연신율 (-1 기본)
  calculated: number   // 계산 후 값
  sum: number          // 합계
  shaded: boolean      // 음영 여부
  aAngle?: number      // A각
}
```

**백엔드 요구:**
- ✅ JSON 컬럼으로 저장
- ⚠️ 계산 로직: 프론트 vs 백엔드 협의 필요

---

### 2. API 엔드포인트 (프론트엔드 가이드)

#### 2.1 품목 CRUD (필수)

```
GET    /api/items
  Query Parameters:
  - itemType?: string (FG,PT,SM,RM,CS)
  - search?: string
  - category1?: string

  Response:
  {
    data: ItemMaster[]
    meta: { total, page, perPage }
  }

GET    /api/items/:itemCode
  Response:
  {
    data: ItemMaster (BOM 포함)
  }

POST   /api/items
  Body: Partial<ItemMaster>
  Response: { data: ItemMaster }

PUT    /api/items/:itemCode
  Body: Partial<ItemMaster>
  Response: { data: ItemMaster }

DELETE /api/items/:itemCode
  Response: { message: "Deleted" }
```

---

#### 2.2 BOM 관리 (필수)

```
GET    /api/items/:itemCode/bom
  Response:
  {
    data: BOMLine[] (flat list)
  }

GET    /api/items/:itemCode/bom/tree
  🔴 Phase 0에서 부재 확인
  Response:
  {
    data: {
      item: ItemMaster
      children: [
        {
          bomLine: BOMLine
          item: ItemMaster
          children: [...] // 재귀
        }
      ]
    }
  }

POST   /api/items/:itemCode/bom
  Body: Partial<BOMLine>
  Response: { data: BOMLine }

PUT    /api/items/:itemCode/bom/:lineId
  Body: Partial<BOMLine>
  Response: { data: BOMLine }

DELETE /api/items/:itemCode/bom/:lineId
  Response: { message: "Deleted" }
```

---

#### 2.3 파일 관리 (필수)

```
POST   /api/items/:itemCode/files
  Body: FormData
  - type: 'specification' | 'certification' | 'bending_diagram'
  - file: File

  Response:
  {
    data: {
      url: string
      fileName: string
      type: string
    }
  }

DELETE /api/items/:itemCode/files/:type
  Response: { message: "Deleted" }
```

---

#### 2.4 동적 템플릿 (선택적, 2차 목표)

```
GET    /api/item-templates
GET    /api/item-templates/:pageId
POST   /api/item-templates
PUT    /api/item-templates/:pageId
DELETE /api/item-templates/:pageId
```

**우선순위:** 🟡 중간 (Phase 2-3 이후)

---

## 🔍 Phase 0 Gap 통합 분석

### 기존 구현 현황 (Phase 0 검증 결과)

| Gap | 설명 | 상태 | 영향 |
|-----|------|------|------|
| #1 | 통합 품목 조회 API | ✅ 해결 | ItemsController 존재 |
| #2 | 치수 연결 매핑 | ❌ 미해결 | dimension_mappings 테이블 필요 |
| #3 | 실시간 견적 계산 | ⚠️ 부분 | BomCalculationController (설계만) |
| #4 | BOM formula 필드 | ❌ 미해결 | product_components.formula 추가 |
| #5 | 조건부 BOM | ❌ 미해결 | product_components.condition 추가 |
| #6 | options/dimensions | ⚠️ 부분 | Material만, Product 없음 |
| #7 | 가격 통합 조회 | ✅ 해결 | PricingService 완성 |

---

### 프론트엔드 가이드 vs Phase 0 Gap

| 프론트 요구사항 | Phase 0 Gap | 우선순위 |
|----------------|-------------|---------|
| ItemMaster 필드 | #6 (options) | 🔴 P0 |
| BOMLine.quantityFormula | #4 (formula) | 🔴 P0 |
| BOM tree API | 신규 발견 | 🔴 P0 |
| 파일 업로드 | 기존 존재 | 🟢 완료 |
| 치수 연결 | #2 | 🟡 P1 |
| 견적 계산 API | #3 | 🟡 P1 |
| 조건부 BOM | #5 | 🟡 P1 |

---

## 🗂️ 데이터베이스 설계

### 1. products 테이블 확장

**현재 구조:**
```sql
-- 기존 필드 (Phase 0 분석)
id, tenant_id, item_code, item_name, item_type
specification, unit, category1, category2, category3
purchase_price, sales_price
attributes (JSON)
created_by, updated_by, deleted_at, timestamps
```

**추가 필요 필드 (프론트 가이드 기반):**
```sql
-- 공통
is_active BOOLEAN DEFAULT true
margin_rate DECIMAL(5,2)
processing_cost DECIMAL(10,2)
labor_cost DECIMAL(10,2)
install_cost DECIMAL(10,2)
safety_stock INT
lead_time INT
is_variable_size BOOLEAN DEFAULT false

-- FG 전용
product_category VARCHAR(20)  -- SCREEN, STEEL
lot_abbreviation VARCHAR(10)
note TEXT

-- PT 전용
part_type VARCHAR(20)         -- ASSEMBLY, BENDING, PURCHASED
part_usage VARCHAR(30)        -- GUIDE_RAIL, BOTTOM_FINISH, ...
installation_type VARCHAR(20)
assembly_type VARCHAR(20)
side_spec_width VARCHAR(20)
side_spec_height VARCHAR(20)
assembly_length VARCHAR(20)
guide_rail_model_type VARCHAR(50)
guide_rail_model VARCHAR(50)

-- 절곡품
bending_diagram VARCHAR(255)  -- 이미지 URL
bending_details JSON          -- BendingDetail[]
material VARCHAR(50)
length VARCHAR(20)
bending_length VARCHAR(20)

-- 인증
certification_number VARCHAR(50)
certification_start_date DATE
certification_end_date DATE
specification_file VARCHAR(255)
specification_file_name VARCHAR(255)
certification_file VARCHAR(255)
certification_file_name VARCHAR(255)

-- 동적 확장 (기존 유지)
options JSON                  -- 🔴 신규 추가 필요
```

**Migration 작업량:** 2-3일

---

### 2. product_components 테이블 확장

**현재 구조:**
```sql
id, tenant_id
parent_product_id, child_product_id (또는 material_id)
quantity, unit, unit_price
note
created_by, updated_by, deleted_at, timestamps
```

**추가 필요 필드:**
```sql
-- 핵심 필드
quantity_formula TEXT         -- 🔴 "W * 2", "H + 100", "G/1000*1.02"
condition TEXT                -- 🔴 "MOTOR='Y'", "WIDTH > 3000"

-- 절곡품
is_bending BOOLEAN DEFAULT false
bending_diagram VARCHAR(255)
bending_details JSON
```

**Migration 작업량:** 1일

---

### 3. 신규 테이블: dimension_mappings

```sql
CREATE TABLE dimension_mappings (
  id BIGSERIAL PRIMARY KEY,
  tenant_id BIGINT NOT NULL,

  parent_item_code VARCHAR(50) NOT NULL,   -- 부모 품목 (예: 세트)
  child_item_code VARCHAR(50) NOT NULL,    -- 자식 품목 (예: 가이드레일)

  source_dimension VARCHAR(20) NOT NULL,   -- 부모 치수명 (예: "W", "H")
  target_dimension VARCHAR(20) NOT NULL,   -- 자식 치수명 (예: "G", "length")

  mapping_formula VARCHAR(100),            -- 변환 공식 (예: "W - 100")

  is_active BOOLEAN DEFAULT true,

  created_by BIGINT,
  updated_by BIGINT,
  deleted_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW(),

  FOREIGN KEY (tenant_id) REFERENCES tenants(id),
  INDEX idx_parent_item (tenant_id, parent_item_code),
  INDEX idx_child_item (tenant_id, child_item_code)
);
```

**Migration 작업량:** 1일

---

### 4. 신규 테이블: item_templates (선택적)

```sql
CREATE TABLE item_templates (
  id BIGSERIAL PRIMARY KEY,
  tenant_id BIGINT NOT NULL,

  page_name VARCHAR(100) NOT NULL,
  item_type VARCHAR(10) NOT NULL,       -- FG, PT, SM, RM, CS

  sections JSON NOT NULL,               -- ItemSection[]

  is_active BOOLEAN DEFAULT true,
  absolute_path VARCHAR(255),

  created_by BIGINT,
  updated_by BIGINT,
  deleted_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW(),

  FOREIGN KEY (tenant_id) REFERENCES tenants(id),
  INDEX idx_item_type (tenant_id, item_type, is_active)
);
```

**우선순위:** 🟡 Phase 2-3 (선택적)

---

## 🔧 백엔드 개발 작업 분류

### Priority 0 (즉시 시작, 1-2주)

#### Task 1.1: products 테이블 Migration
- [ ] Migration 파일 작성
- [ ] 프론트 가이드 필드 추가 (공통 + FG + PT + 인증)
- [ ] options JSON 컬럼 추가
- [ ] Rollback 스크립트 준비

**예상 시간:** 1일

---

#### Task 1.2: product_components 테이블 Migration
- [ ] quantity_formula TEXT 컬럼 추가
- [ ] condition TEXT 컬럼 추가
- [ ] is_bending, bending_diagram, bending_details 추가
- [ ] Rollback 스크립트

**예상 시간:** 0.5일

---

#### Task 1.3: ItemsController 확장
- [ ] GET /api/items - 필터링 (itemType, search, category1)
- [ ] GET /api/items/:itemCode - BOM 포함 응답
- [ ] POST /api/items - 유형별 검증 (FG/PT/SM/RM/CS)
- [ ] PUT /api/items/:itemCode
- [ ] DELETE /api/items/:itemCode (Soft Delete)

**예상 시간:** 3일

---

#### Task 1.4: BOMController 신규 개발
- [ ] GET /api/items/:itemCode/bom - flat list
- [ ] GET /api/items/:itemCode/bom/tree - 계층 구조 (재귀)
- [ ] POST /api/items/:itemCode/bom
- [ ] PUT /api/items/:itemCode/bom/:lineId
- [ ] DELETE /api/items/:itemCode/bom/:lineId

**예상 시간:** 3-4일

---

#### Task 1.5: FileController 확장
- [ ] POST /api/items/:itemCode/files
  - type: specification, certification, bending_diagram
  - 파일 검증 (확장자, 크기)
  - Storage 저장 (local or S3)
  - URL 반환
- [ ] DELETE /api/items/:itemCode/files/:type

**예상 시간:** 2일

---

### Priority 1 (2주차, 1-2주)

#### Task 2.1: dimension_mappings 테이블
- [ ] Migration 작성
- [ ] DimensionMapping 모델 생성
- [ ] API: GET/POST/PUT/DELETE /api/dimension-mappings

**예상 시간:** 2일

---

#### Task 2.2: BOM 계산 로직 강화
- [ ] quantityFormula 파싱 (수식 계산)
- [ ] 변수 지원 (W, H, G, length 등)
- [ ] 에러 핸들링 (잘못된 수식)
- [ ] POST /api/quotes/calculate
  - 입력: itemCode + dimensions (W, H)
  - 출력: BOM 전개 + 수량 계산 + 원가

**예상 시간:** 3-4일

---

#### Task 2.3: 조건부 BOM
- [ ] condition 필드 파싱 (조건 평가)
- [ ] 조건부 BOM 필터링 로직
- [ ] API 통합

**예상 시간:** 2-3일

---

### Priority 2 (3-4주차, 선택적)

#### Task 3.1: 동적 템플릿 시스템
- [ ] item_templates 테이블
- [ ] ItemTemplateController
- [ ] GET/POST/PUT/DELETE /api/item-templates

**예상 시간:** 3-4일

---

#### Task 3.2: 성능 최적화
- [ ] BOM tree 조회 성능 (N+1 문제 해결)
- [ ] Eager Loading
- [ ] Cache 전략 (Redis)
- [ ] 인덱싱 최적화

**예상 시간:** 2-3일

---

## 📅 백엔드 개발 타임라인

### Week 1-2: 핵심 API 개발 (P0)

```
Day 1-2:
✅ products 테이블 Migration
✅ product_components Migration
✅ Migration 실행 및 검증

Day 3-5:
✅ ItemsController 확장
  - GET /api/items (필터링)
  - GET /api/items/:itemCode (BOM 포함)
  - POST/PUT/DELETE

Day 6-9:
✅ BOMController 신규
  - CRUD API
  - Tree 구조 조회 (재귀)

Day 10-12:
✅ FileController 확장
  - 파일 업로드 (3가지 타입)
  - 파일 삭제
  - Storage 연동

Day 13-14:
✅ 통합 테스트
✅ Postman Collection 작성
```

---

### Week 3-4: BOM 계산 및 매핑 (P1)

```
Day 15-16:
✅ dimension_mappings 테이블
✅ DimensionMappingController

Day 17-20:
✅ BOM 계산 로직
  - quantityFormula 파싱
  - 변수 지원 (W, H, G)
  - POST /api/quotes/calculate

Day 21-23:
✅ 조건부 BOM
  - condition 필드 파싱
  - 조건 평가 로직

Day 24-28:
✅ 통합 테스트
✅ 성능 테스트
✅ 버그 수정
```

---

### Week 5-6: 선택적 확장 (P2)

```
Day 29-32:
🎯 동적 템플릿 시스템 (선택)
  - item_templates 테이블
  - Template API

Day 33-35:
🎯 성능 최적화
  - Eager Loading
  - Cache
  - 인덱싱

Day 36-42:
🎯 문서화
🎯 배포 준비
```

---

## 🧪 테스트 전략

### Unit Test (PHPUnit)

```php
// tests/Unit/Services/BomCalculationServiceTest.php
class BomCalculationServiceTest extends TestCase
{
    /** @test */
    public function it_calculates_formula_with_variables()
    {
        $service = new BomCalculationService();

        $formula = "W * 2 + H";
        $variables = ['W' => 3500, 'H' => 2000];

        $result = $service->evaluateFormula($formula, $variables);

        $this->assertEquals(9000, $result); // 3500*2 + 2000
    }

    /** @test */
    public function it_builds_bom_tree_recursively()
    {
        $item = Product::factory()->create();
        // ...

        $tree = $service->buildBomTree($item->item_code);

        $this->assertArrayHasKey('children', $tree);
    }
}
```

---

### API Test (Feature Test)

```php
// tests/Feature/Api/ItemsControllerTest.php
class ItemsControllerTest extends TestCase
{
    /** @test */
    public function it_lists_items_with_filtering()
    {
        $response = $this->getJson('/api/items?itemType=FG&search=test');

        $response->assertStatus(200)
                 ->assertJsonStructure([
                     'data' => [
                         '*' => ['id', 'itemCode', 'itemName', 'itemType']
                     ],
                     'meta' => ['total', 'page', 'perPage']
                 ]);
    }

    /** @test */
    public function it_creates_item_with_validation()
    {
        $data = [
            'itemName' => 'Test Product',
            'itemType' => 'FG',
            'unit' => 'EA',
            // ...
        ];

        $response = $this->postJson('/api/items', $data);

        $response->assertStatus(201)
                 ->assertJsonFragment(['itemName' => 'Test Product']);
    }
}
```

---

### Postman Collection

```json
{
  "info": {
    "name": "BP-MES Items API",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "품목 목록 조회",
      "request": {
        "method": "GET",
        "url": "{{baseUrl}}/api/items?itemType=FG&search=&category1="
      }
    },
    {
      "name": "품목 상세 조회",
      "request": {
        "method": "GET",
        "url": "{{baseUrl}}/api/items/:itemCode"
      }
    },
    {
      "name": "BOM Tree 조회",
      "request": {
        "method": "GET",
        "url": "{{baseUrl}}/api/items/:itemCode/bom/tree"
      }
    }
  ]
}
```

---

## 📝 API 문서화 (Swagger)

### Swagger 주석 예시

```php
/**
 * @OA\Get(
 *     path="/api/items",
 *     summary="품목 목록 조회",
 *     tags={"Items"},
 *     security={{"sanctum":{}}},
 *     @OA\Parameter(
 *         name="itemType",
 *         in="query",
 *         description="품목 유형 (FG,PT,SM,RM,CS)",
 *         required=false,
 *         @OA\Schema(type="string", enum={"FG","PT","SM","RM","CS"})
 *     ),
 *     @OA\Parameter(
 *         name="search",
 *         in="query",
 *         description="검색어 (품목명, 품목코드)",
 *         required=false,
 *         @OA\Schema(type="string")
 *     ),
 *     @OA\Response(
 *         response=200,
 *         description="성공",
 *         @OA\JsonContent(
 *             @OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/ItemMaster")),
 *             @OA\Property(property="meta", ref="#/components/schemas/PaginationMeta")
 *         )
 *     )
 * )
 */
public function index(Request $request)
{
    // ...
}
```

---

## ⚙️ 개발 환경 설정

### .env 설정

```bash
# Laravel API
APP_NAME="BP-MES API"
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost:8000

# Database
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=bp_mes
DB_USERNAME=postgres
DB_PASSWORD=

# File Storage
FILESYSTEM_DISK=local
# FILESYSTEM_DISK=s3
# AWS_ACCESS_KEY_ID=
# AWS_SECRET_ACCESS_KEY=
# AWS_DEFAULT_REGION=
# AWS_BUCKET=

# CORS (Next.js 프론트엔드)
CORS_ALLOWED_ORIGINS=http://localhost:3000,https://your-frontend-domain.com
```

---

### CORS 설정

```php
// config/cors.php
return [
    'paths' => ['api/*', 'sanctum/csrf-cookie'],
    'allowed_methods' => ['*'],
    'allowed_origins' => explode(',', env('CORS_ALLOWED_ORIGINS', '*')),
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => true,
];
```

---

## 🚨 주의사항

### 1. Multi-tenancy

**모든 API는 tenant_id 기반 필터링 필수:**

```php
// ItemsController.php
public function index(Request $request)
{
    $tenantId = auth()->user()->tenant_id;

    $items = Product::where('tenant_id', $tenantId)
        ->when($request->itemType, fn($q, $v) => $q->where('item_type', $v))
        ->when($request->search, fn($q, $v) => $q->where('item_name', 'like', "%{$v}%"))
        ->get();

    return response()->json(['data' => $items]);
}
```

---

### 2. Soft Delete

**삭제는 항상 Soft Delete:**

```php
// Product 모델
use Illuminate\Database\Eloquent\SoftDeletes;

class Product extends Model
{
    use SoftDeletes, BelongsToTenant;

    protected $dates = ['deleted_at'];
}
```

---

### 3. Audit Log

**변경 이력 기록:**

```php
// 품목 수정 시
AuditLog::create([
    'tenant_id' => $tenantId,
    'user_id' => auth()->id(),
    'action' => 'update',
    'model' => 'Product',
    'model_id' => $product->id,
    'changes' => [
        'before' => $product->getOriginal(),
        'after' => $product->getAttributes(),
    ],
]);
```

---

### 4. 파일 업로드 검증

```php
// FileController.php
public function upload(Request $request, $itemCode)
{
    $request->validate([
        'type' => 'required|in:specification,certification,bending_diagram',
        'file' => 'required|file|max:10240|mimes:pdf,jpg,jpeg,png',
    ]);

    $type = $request->type;
    $file = $request->file('file');

    // 파일 저장
    $path = $file->store("items/{$itemCode}/{$type}", 'public');
    $url = Storage::url($path);

    // DB 업데이트
    $item = Product::where('item_code', $itemCode)->firstOrFail();

    if ($type === 'specification') {
        $item->specification_file = $url;
        $item->specification_file_name = $file->getClientOriginalName();
    } elseif ($type === 'certification') {
        $item->certification_file = $url;
        $item->certification_file_name = $file->getClientOriginalName();
    } elseif ($type === 'bending_diagram') {
        $item->bending_diagram = $url;
    }

    $item->save();

    return response()->json([
        'data' => [
            'url' => $url,
            'fileName' => $file->getClientOriginalName(),
            'type' => $type,
        ]
    ]);
}
```

---

## 📚 참고 문서

### 프로젝트 문서
- **프론트엔드 가이드:** `ITEM_MANAGEMENT_MIGRATION_GUIDE.md`
- **Phase 0 보고서:** `PHASE_0_FINAL_REPORT.md`
- **Gap 검증:** `api_gap_validation_report.md`
- **아키텍처 옵션:** `ARCHITECTURE_OPTIONS_CORE.md`

### Laravel 문서
- [Laravel 12 Documentation](https://laravel.com/docs/12.x)
- [Eloquent ORM](https://laravel.com/docs/12.x/eloquent)
- [API Resources](https://laravel.com/docs/12.x/eloquent-resources)
- [File Storage](https://laravel.com/docs/12.x/filesystem)

---

## 🎯 다음 단계

### 즉시 시작:
1. **Migration 파일 작성** (products, product_components 확장)
2. **ItemsController 리뷰** (기존 구현 확인)
3. **BOMController 설계** (tree API 구조)

### 협의 필요:
- [ ] 절곡품 계산 로직: 프론트 vs 백엔드?
- [ ] 파일 저장소: Local vs S3?
- [ ] BOM 계산 API 응답 형식 확정
- [ ] quantityFormula 수식 파싱 라이브러리 선택

### 준비 사항:
- [ ] 개발 서버 환경 확인
- [ ] PostgreSQL/MySQL 준비
- [ ] Postman 설치
- [ ] Git branch 전략

---

**작성일:** 2025-11-13
**버전:** 2.0 (프론트엔드 가이드 통합)
**다음 업데이트:** Migration 완료 후
