docs: [order] 재고생산관리 API 명세 추가

- frontend/api-specs/stock-production-api.md 신규 작성
- INDEX.md에 재고생산관리 API 문서 등록
This commit is contained in:
김보곤
2026-03-16 21:27:17 +09:00
parent 2073af1d8e
commit 054d5d23f7
2 changed files with 351 additions and 0 deletions

View File

@@ -24,6 +24,7 @@
| 견적관리 | `features/quotes/README.md` | 견적 시스템, BOM 계산 |
| 급여관리 API | `frontend/api-specs/payroll-api.md` | 급여관리 API 전체 명세 (18개 엔드포인트) |
| 바로빌 회계 API | `frontend/api-specs/barobill-api.md` | 카드/은행/홈택스 REST API (42개 엔드포인트) |
| 재고생산관리 API | `frontend/api-specs/stock-production-api.md` | 재고생산 API 명세 (기존 수주 API + STOCK 타입) |
| 결재관리 | `dev/dev_plans/approval-system-unification-plan.md` | MNG→API 결재 통합 계획 |
| API 품질 | `system/api-code-quality-audit.md` | 정석 패턴 R1~R6, 안티패턴, 보안, 체크리스트 |
| API 학습 | `dev/guides/api-request-lifecycle.md` | Client API로 배우는 요청 생명주기 8단계 |
@@ -262,6 +263,7 @@ DB 도메인별:
| [barobill-api.md](frontend/api-specs/barobill-api.md) | 바로빌 회계 데이터 API 명세 (42개 엔드포인트) |
| [equipment-api.md](requests/equipment-frontend-request.md) | 설비관리 React 프론트엔드 구현 요청 (26개 엔드포인트 + 화면 가이드) |
| [vehicle-api.md](frontend/api-specs/vehicle-api.md) | 차량관리 API 명세 (20개 엔드포인트: 차량목록, 차량일지, 정비이력, 사진) |
| [stock-production-api.md](frontend/api-specs/stock-production-api.md) | 재고생산관리 API 명세 (기존 수주 API + STOCK 타입) |
| [vehicle-react-implementation.md](plans/vehicle-react-implementation.md) | 차량관리 React 구현 요청서 (3개 메뉴, 컴포넌트 구조, 타입 정의) |
### frontend/integration/ — 프론트엔드 개발 가이드

View File

@@ -0,0 +1,349 @@
# 재고생산관리 API 명세
> **작성일**: 2026-03-16
> **상태**: 설계 확정
> **대상**: React 프론트엔드 개발자
---
## 1. 개요
### 1.1 목적
재고생산관리는 **수주 없이 재고 목적으로 생산**하는 경우를 위한 기능이다.
기존 수주관리(Order) API를 **그대로 사용**하되, `order_type_code: 'STOCK'`으로 구분한다.
### 1.2 핵심 원칙
- 별도 API 엔드포인트 없음 — 기존 `/api/v1/orders` 사용
- `order_type_code` 필터로 수주(`ORDER`)와 재고생산(`STOCK`)을 분리
- 화면은 수주관리를 **단순화**한 형태 (거래처, 견적, 배송, 할인 등 불필요)
- 하류 시스템(작업지시, 생산, 출하)은 **동일하게 동작**
---
## 2. API 엔드포인트
> **기본 URL**: `/api/v1/orders`
> **인증**: `Bearer Token` (Sanctum) + `API Key`
### 2.1 목록 조회
```
GET /api/v1/orders?order_type=STOCK
```
| 파라미터 | 타입 | 필수 | 설명 |
|----------|------|:----:|------|
| `order_type` | string | ✅ | `STOCK` 고정 |
| `page` | int | - | 페이지 (기본: 1) |
| `size` | int | - | 페이지 크기 (기본: 20) |
| `q` | string | - | 검색어 (생산번호, 메모) |
| `status` | string | - | 상태 필터 (`DRAFT`, `CONFIRMED` 등) |
| `date_from` | date | - | 등록일 시작 |
| `date_to` | date | - | 등록일 종료 |
**응답 예시**:
```json
{
"success": true,
"message": "message.order.fetched",
"data": {
"data": [
{
"id": 42,
"order_no": "STK202603160001",
"order_type_code": "STOCK",
"status_code": "DRAFT",
"quantity": "100.0000",
"memo": "봄 시즌 대비 재고 확보",
"options": {
"production_reason": "시즌 대비",
"target_stock_qty": 500
},
"items": [
{
"id": 1,
"item_name": "25mm 알루미늄 블라인드",
"specification": "W1000 x H2000",
"quantity": "100.0000",
"unit_price": "15000.00"
}
],
"created_at": "2026-03-16T10:30:00Z"
}
],
"current_page": 1,
"last_page": 1,
"total": 1
}
}
```
---
### 2.2 통계 조회
```
GET /api/v1/orders/stats?order_type=STOCK
```
| 파라미터 | 타입 | 필수 | 설명 |
|----------|------|:----:|------|
| `order_type` | string | ✅ | `STOCK` 고정 |
**응답 예시**:
```json
{
"success": true,
"data": {
"total": 15,
"draft": 3,
"confirmed": 5,
"in_progress": 4,
"completed": 2,
"cancelled": 1,
"total_amount": 0,
"confirmed_amount": 0
}
}
```
---
### 2.3 생성
```
POST /api/v1/orders
```
**요청 본문**:
```json
{
"order_type_code": "STOCK",
"memo": "봄 시즌 대비 재고 확보",
"options": {
"production_reason": "시즌 대비",
"target_stock_qty": 500
},
"items": [
{
"item_id": 10,
"item_name": "25mm 알루미늄 블라인드",
"specification": "W1000 x H2000",
"quantity": 100,
"unit_price": 0,
"unit": "EA"
}
]
}
```
**필수 필드**:
| 필드 | 타입 | 필수 | 설명 |
|------|------|:----:|------|
| `order_type_code` | string | ✅ | `STOCK` 고정 |
| `items` | array | ✅ | 생산할 품목 목록 |
| `items[].item_name` | string | ✅ | 품목명 |
| `items[].quantity` | number | ✅ | 수량 |
| `items[].unit_price` | number | ✅ | 단가 (재고생산은 `0` 가능) |
**선택 필드**:
| 필드 | 타입 | 설명 |
|------|------|------|
| `memo` | string | 비고 |
| `options.production_reason` | string | 생산 사유 |
| `options.target_stock_qty` | number | 목표 재고 수량 |
| `items[].item_id` | int | 품목 마스터 ID |
| `items[].specification` | string | 규격 |
| `items[].unit` | string | 단위 |
**사용하지 않는 필드** (수주 전용):
```
❌ client_id, client_name, client_contact → 거래처 없음
❌ site_name → 현장 없음
❌ quote_id → 견적 없음
❌ delivery_date, delivery_method_code → 납기/배송 불필요
❌ discount_rate, discount_amount → 할인 없음
❌ sales_recognition → 매출 인식 불필요
❌ options.shipping_cost_code → 운임비용 불필요
❌ options.receiver, receiver_contact → 수신자 불필요
❌ options.shipping_address → 배송지 불필요
```
> **자동 생성**: `order_no`는 `STK{YYYYMMDD}{NNNN}` 형식으로 서버에서 자동 생성
---
### 2.4 단건 조회
```
GET /api/v1/orders/{id}
```
기존 수주 조회와 동일. `order_type_code``STOCK`인지 프론트에서 확인.
---
### 2.5 수정
```
PUT /api/v1/orders/{id}
```
생성과 동일한 필드 사용. `order_type_code`는 변경하지 않는다.
---
### 2.6 삭제
```
DELETE /api/v1/orders/{id}
```
기존 수주 삭제와 동일.
---
### 2.7 상태 변경
```
PATCH /api/v1/orders/{id}/status
```
```json
{
"status": "CONFIRMED"
}
```
**상태 흐름** (수주와 동일):
```
DRAFT → CONFIRMED → IN_PROGRESS → COMPLETED
└─────→ CANCELLED ──→ DRAFT (복구)
```
> **재고생산 특수**: `CONFIRMED` 상태 진입 시 매출 자동 생성이 **발생하지 않음**
---
### 2.8 생산지시 생성
```
POST /api/v1/orders/{id}/production-order
```
수주와 동일하게 작업지시(WorkOrder)를 생성한다.
```json
{
"process_ids": [1, 2, 3],
"priority": "normal",
"scheduled_date": "2026-03-20",
"memo": "재고생산 작업"
}
```
---
## 3. 채번 규칙
| 주문 유형 | 접두사 | 예시 |
|----------|--------|------|
| 수주 (ORDER) | `ORD` | `ORD202603160001` |
| 재고생산 (STOCK) | `STK` | `STK202603160001` |
---
## 4. 화면 설계 가이드
### 4.1 수주관리 화면 vs 재고생산관리 화면
```
┌─ 수주관리 ──────────────────┐ ┌─ 재고생산관리 ───────────────┐
│ │ │ │
│ [거래처 정보] │ │ [생산 정보] │
│ - 거래처 선택 │ │ - 생산 사유 (텍스트) │
│ - 현장명 │ │ - 목표 재고 수량 │
│ - 배송/납기일 │ │ - 비고 │
│ - 운임비용 │ │ │
│ - 견적 연결 │ ├──────────────────────────────┤
│ - 할인 │ │ [품목 목록] │
│ - 매출 인식 방식 │ │ - 품목 선택 │
│ │ │ - 수량 │
│ [개소/구역 (OrderNode)] │ │ - 규격 │
│ - N-depth 트리 구조 │ │ │
│ │ │ (단가/금액/할인 불필요) │
│ [품목 목록] │ │ (개소/구역 불필요) │
│ - 품목, 수량, 단가, 할인 │ │ │
│ - floor_code, symbol_code │ └──────────────────────────────┘
│ - 금액 계산 │
│ │
└──────────────────────────────┘
```
### 4.2 목록 페이지 표시 컬럼
| 컬럼 | 설명 |
|------|------|
| 생산번호 | `order_no` (STK...) |
| 상태 | `status_code` (상태 배지) |
| 품목 | 대표 품목명 + (외 N건) |
| 수량 | 총 수량 |
| 생산 사유 | `options.production_reason` |
| 등록일 | `created_at` |
### 4.3 상태 배지 색상 (수주와 동일)
| 상태 | 라벨 | 색상 |
|------|------|------|
| `DRAFT` | 등록 | gray |
| `CONFIRMED` | 확정 | blue |
| `IN_PROGRESS` | 진행중 | yellow |
| `IN_PRODUCTION` | 생산중 | orange |
| `PRODUCED` | 생산완료 | green |
| `COMPLETED` | 완료 | green |
| `CANCELLED` | 취소 | red |
---
## 5. 구현 체크리스트
### 프론트엔드 (React)
- [ ] 재고생산관리 메뉴/라우트 추가
- [ ] 목록 페이지: `GET /api/v1/orders?order_type=STOCK`
- [ ] 통계 카드: `GET /api/v1/orders/stats?order_type=STOCK`
- [ ] 생성 폼: `order_type_code: 'STOCK'` 필수 전송
- [ ] 상세/수정 페이지: 수주 화면 단순화 (거래처/견적/배송/할인 제거)
- [ ] 생산지시 생성 버튼: `POST /api/v1/orders/{id}/production-order`
- [ ] 상태 변경: `PATCH /api/v1/orders/{id}/status`
### 백엔드 (API) — 완료
- [x] `Order::TYPE_STOCK = 'STOCK'` 상수 추가
- [x] StoreOrderRequest에 `STOCK` validation 추가
- [x] UpdateOrderRequest에 `STOCK` validation 추가
- [x] 재고생산 채번: `STK{YYYYMMDD}{NNNN}`
- [x] stats()에 `order_type` 필터 추가
- [x] STOCK 타입 확정 시 매출 자동 생성 스킵
- [x] options에 `production_reason`, `target_stock_qty` 필드 추가
---
## 관련 문서
- 수주관리: 기존 수주 API는 동일 엔드포인트 (`/api/v1/orders`)
- 작업지시: `POST /api/v1/orders/{id}/production-order`
- 품목관리: `rules/item-policy.md`
---
**최종 업데이트**: 2026-03-16