---
source: api/claudedocs/SAM_Item_DB_API_Analysis_v3_FINAL.md
section: 전체 요약
created: 2025-11-10
bp_mes_phase: Phase A - Step A.1
related:
  - api_db_modeling.md
  - api_logical_relationships.md
tags: [api, item, pricing, bom, analysis]
---

# API 품목 분석 요약 (v3 FINAL)

**분석일:** 2025-11-11
**원본 문서:** 1,262줄
**핵심 발견:** 가격 시스템 완전 구현됨, 통합 품목 조회 API 부재

---

## Executive Summary

### 🎉 주요 발견사항 (긍정적)

**가격 시스템이 이미 완전히 구현되어 있음:**
- `price_histories` 테이블 (14 컬럼)
- Pricing API 5개 엔드포인트
- PricingService 완전 구현
- Swagger 문서화 완료

**가격 시스템 핵심 기능:**
1. **다형성 가격 관리**: item_type_code (PRODUCT|MATERIAL) + item_id
2. **가격 유형 구분**: price_type_code (SALE=판매가, PURCHASE=매입가)
3. **고객그룹별 차별 가격**: client_group_id (NULL=기본, 값=그룹별)
4. **시계열 이력 관리**: started_at ~ ended_at (기간별 가격 변동)
5. **우선순위 조회**: 고객그룹 가격 → 기본 가격 fallback

---

### ⚠️ 주요 문제점

#### 1. 통합 품목 조회 API 부재 (🔴 Critical)

**현재 상황:**
- materials와 products가 별도 API로 분리
- 프론트엔드에서 "모든 품목" 조회 시 2번 API 호출 필요

**문제점:**
```
GET /api/v1/products   # 제품/부품만
GET /api/v1/materials  # 자재만

→ 프론트엔드에서 수동 병합 필요
→ API 호출 효율 50% 손실
```

**개선안:**
```
GET /api/v1/items?type=FG,PT,SM,RM,CS&search=...

// UNION 쿼리로 통합 조회
(SELECT 'PRODUCT' as item_type, * FROM products ...)
UNION ALL
(SELECT 'MATERIAL' as item_type, * FROM materials ...)
```

**예상 효과:**
- API 호출 50% 감소
- 프론트엔드 로직 30% 단순화
- BOM 조회 성능 향상

---

#### 2. 프론트-백엔드 가격 데이터 매핑 불일치 (🔴 Critical)

**프론트엔드 기대 구조:**
```typescript
interface ItemMaster {
  purchasePrice?: number;  // 단일 값
  salesPrice?: number;     // 단일 값
  marginRate?: number;
}
```

**백엔드 실제 구조:**
```sql
-- 시계열 + 고객별 다중 레코드
price_histories:
  - 2024-01-01 ~ 2024-06-30: 40,000원
  - 2024-07-01 ~ 2024-12-31: 45,000원
  - 2025-01-01 ~ NULL: 50,000원 (현재)
  - 고객 A: 55,000원 (그룹별 가격)
```

**매핑 불일치:**
| 측면 | 프론트 | 백엔드 | 문제 |
|------|--------|--------|------|
| 데이터 구조 | 단일 값 | 시계열 배열 | 어떤 값을 보여줄지 불명확 |
| 고객 차별화 | 표현 불가 | client_group_id | 고객별 가격 표시 방법? |
| 시계열 | 현재만 | 과거-현재-미래 | 이력 UI 부재 |

**해결 방안 B (✅ 권장):**
- ItemMaster에서 가격 필드 제거
- 별도 PriceManagement 컴포넌트로 가격 이력 UI 제공
- 견적 산출 시 동적 가격 조회

**해결 방안 C (✅ 권장 보완):**
```
GET /api/v1/items/10?include_price=true&client_id=5&price_date=2025-11-11

→ {
  item: { ... },
  prices: {
    sale: 55000,
    purchase: 40000,
    client_group_id: 3
  }
}
```

---

#### 3. 품목 타입 구분 불명확 (🟡 Important)

**현재 상황:**
- materials 테이블: 타입 구분 필드 없음 (category로만 구분)
- products 테이블: product_type 있지만 활용 미흡

**개선안:**
1. materials에 `material_type` VARCHAR(20) 추가
   - 값: 'RM' (원자재), 'SM' (부자재), 'CS' (소모품)
2. products의 `product_type` 활용 강화
   - 값: 'FG' (완제품), 'PT' (부품)

---

## 데이터베이스 현황

### 1. materials 테이블 (18 컬럼)
- **핵심 필드**: name, item_name, specification, material_code, unit
- **분류**: category_id (외래키)
- **검색**: search_tag (text), material_code (unique)
- **확장**: attributes (json), options (json)
- **특징**: 타입 구분 필드 없음, 가격은 price_histories로 별도 관리

### 2. products 테이블 (18 컬럼)
- **핵심 필드**: code, name, unit, product_type, category_id
- **플래그**: is_sellable, is_purchasable, is_producible, is_active
- **확장**: attributes (json)
- **특징**: tenant_id+code unique, 가격은 price_histories로 별도 관리

### 3. price_histories 테이블 (14 컬럼) ✅ 완전 구현
```sql
{
  "item_type_code": "PRODUCT | MATERIAL",
  "item_id": "다형성 참조",
  "price_type_code": "SALE | PURCHASE",
  "client_group_id": "NULL=기본, 값=그룹별",
  "price": "DECIMAL(18,4)",
  "started_at": "시계열 시작",
  "ended_at": "시계열 종료 (NULL=현재)"
}
```

**복합 인덱스:**
```
idx_price_histories_main:
  (tenant_id, item_type_code, item_id, client_group_id, started_at)
```

### 4. product_components 테이블 (14 컬럼)
- **BOM 구조**: parent_product_id → (ref_type, ref_id)
- **다형성**: ref_type ('material' | 'product') + ref_id
- **수량**: quantity (decimal 18,6)
- **특징**: 실제 제품의 BOM (설계 템플릿과 별도)

### 5. bom_templates 테이블 (12 컬럼)
- **설계 BOM**: model_version_id 기반
- **계산 공식**: calculation_schema (json)
- **특징**: 설계 단계의 BOM 템플릿

---

## API 엔드포인트 현황

### Products API (7개)
```
GET    /api/v1/products          - index
POST   /api/v1/products          - store
GET    /api/v1/products/{id}     - show
PUT    /api/v1/products/{id}     - update
DELETE /api/v1/products/{id}     - destroy
GET    /api/v1/products/search   - search ✅
POST   /api/v1/products/{id}/toggle - toggle
```

### Materials API (5개)
```
GET    /api/v1/materials         - index
POST   /api/v1/materials         - store
GET    /api/v1/materials/{id}    - show
PUT    /api/v1/materials/{id}    - update
DELETE /api/v1/materials/{id}    - destroy
```
⚠️ **누락**: search 엔드포인트 없음

### Pricing API (5개) ✅ 완전 구현
```
GET    /api/v1/pricing           - index (가격 이력 목록)
GET    /api/v1/pricing/show      - show (단일 품목 가격, 고객별/날짜별)
POST   /api/v1/pricing/bulk      - bulk (여러 품목 일괄 조회)
POST   /api/v1/pricing/upsert    - upsert (가격 등록/수정)
DELETE /api/v1/pricing/{id}      - destroy
```

**주요 기능:**
- 우선순위 조회 (고객그룹 → 기본 가격)
- 시계열 조회 (validAt scope)
- 일괄 조회 (BOM 원가 계산용)
- 경고 메시지 (가격 없을 경우)

---

## 수정된 우선순위별 개선 제안

### 🔴 High Priority (Week 1-4)

#### 제안 1: 통합 품목 조회 API 신설
```php
// ItemsController::index()
GET /api/v1/items?type=FG,PT,SM,RM,CS&search=...

// UNION 쿼리
(SELECT 'PRODUCT' as item_type, id, code, name, ...
 FROM products WHERE ...)
UNION ALL
(SELECT 'MATERIAL' as item_type, id, material_code as code, name, ...
 FROM materials WHERE ...)
```

**예상 효과:**
- API 호출 50% 감소 (2번 → 1번)
- 프론트엔드 로직 30% 단순화

#### 제안 2: 품목-가격 통합 조회 엔드포인트
```
GET /api/v1/items/10?include_price=true&client_id=5&price_date=2025-11-11

→ {
  item: { ... },
  prices: {
    sale: 55000,
    purchase: 40000,
    sale_history_id: 125
  }
}
```

**예상 효과:**
- API 호출 50% 감소
- BOM 원가 계산 최적화

---

### 🟡 Medium Priority (Week 5-8)

#### 제안 3: 품목 타입 구분 명확화
```sql
-- materials 테이블
ALTER TABLE materials
ADD COLUMN material_type VARCHAR(20) NULL
  COMMENT 'RM(원자재), SM(부자재), CS(소모품)';

-- products 테이블
UPDATE products SET product_type = 'FG' WHERE product_type = 'PRODUCT';
```

#### 제안 4: BOM 시스템 관계 문서화
- LOGICAL_RELATIONSHIPS.md 업데이트
- 설계 워크플로우 명확화
- 제품화 프로세스 문서화

---

### 🟢 Low Priority (Week 9-12)

#### 제안 5: 가격 이력 UI 컴포넌트 (React)
```tsx
<PriceHistoryTable
  itemType="PRODUCT"
  itemId={10}
  clientGroupId={null}
/>

// 표시:
// - 과거 가격 (회색)
// - 현재 가격 (녹색, 굵게)
// - 미래 가격 (파란색)
// - 고객그룹별 탭
```

#### 제안 6: Materials API search 엔드포인트 추가
```
GET /api/v1/materials/search?q=스크린&material_type=SM
```

---

## 마이그레이션 전략

### Phase 1 (Week 1-2): 통합 품목 조회 API
1. ItemsService 생성
2. ItemsController 생성
3. 라우트 추가
4. Swagger 문서 작성
5. 통합 테스트

**검증 기준:**
- `/api/v1/items?type=FG,PT,SM&search=...` 정상 동작
- UNION 쿼리 성능 테스트 (1,000건 이상)
- Swagger 100%

### Phase 2 (Week 3-4): 품목-가격 통합 조회
1. ItemsController::show() 수정 (`include_price` 옵션)
2. Pricing API 연동
3. Swagger 업데이트
4. 통합 테스트

**검증 기준:**
- 고객별, 날짜별 가격 조회 100%
- 정확도 100%

### Phase 3 (Week 5-6): 가격 이력 UI
1. PriceHistoryTable 컴포넌트
2. PriceManagement 컴포넌트
3. 견적 산출 동적 가격 조회
4. ItemMaster 타입에서 price 필드 제거

### Phase 4 (Week 7-8): 품목 타입 구분
1. material_type 컬럼 추가 마이그레이션
2. MaterialService 수정
3. 기존 데이터 마이그레이션
4. 통합 API에 타입 필터링 적용

---

## 결론

### 핵심 메시지
> "가격 시스템은 이미 완성되어 있습니다. 이제 프론트엔드와의 통합만 남았습니다."

### 예상 효과

| 지표 | Before | After | 개선율 |
|------|--------|-------|-------|
| API 호출 효율 | 2번 호출 | 1번 호출 | **50% 향상** |
| 프론트 복잡도 | 별도 처리 | 통합 API | **30% 감소** |
| 가격 시스템 | 백 90%, 프 0% | 백 100%, 프 100% | **+10% / +100%** |
| 타입 필터링 | category 추론 | material_type | **30% 향상** |

### 최종 권장사항

1. **즉시 시작**: 통합 품목 조회 API (Week 1-2)
2. **병행 추진**: 품목-가격 통합 조회 (Week 3-4)
3. **단계적 개선**: 가격 UI → 타입 구분 → 문서화 (Week 5-8)

---

**문서 버전:** v3 FINAL 요약본
**작성일:** 2025-11-12 (BP-MES Phase A.1)
**다음 문서:** api_db_modeling.md