# 적정재고 관리 기능 기획

> **작성일**: 2026-03-20
> **상태**: 기획
> **담당**: R&D실

---

## 1. 개요

### 1.1 목적

재고 상세 화면에 **적정재고** 개념을 추가하여, 단순 최소치 확보(안전재고)를 넘어 **범위 기반 재고 관리**를 가능하게 한다.

### 1.2 핵심 개념

| 구분 | 안전재고 (Safety Stock) | 적정재고 (Optimal Stock) |
|------|----------------------|------------------------|
| **정의** | 결품 방지를 위한 **최소 보유량** | 효율적 운영을 위한 **범위 (최소~최대)** |
| **관리 기준** | 단일 값 (최소치) | 최소 ~ 최대 범위 |
| **역할** | "이 이하로 떨어지면 안 된다" → 발주 트리거 | "이 범위 안에 있어야 정상이다" → 과잉재고 방지 + 결품 방지 |
| **알림** | 재고 < 안전재고 → `low` 상태 | 재고 > 최대재고 → `over` 상태 |

### 1.3 개선 범위

- `stocks` 테이블에 `max_stock` 컬럼 추가
- `Stock` 모델 상태 계산 로직 확장 (`over` 상태 추가)
- React 재고 상세 화면에 적정재고(최소/최대) 입력 UI 추가
- 재고 목록에서 `over` 상태 표시

---

## 2. 현재 상태

### 2.1 DB 스키마 (stocks 테이블)

```sql
safety_stock  DECIMAL(15,3)  DEFAULT 0  COMMENT '안전 재고'
-- max_stock 컬럼 없음
```

### 2.2 상태 계산 로직 (`Stock::calculateStatus()`)

```php
if ($this->stock_qty <= 0)              return 'out';     // 재고 없음
if ($this->stock_qty < $this->safety_stock) return 'low'; // 부족
return 'normal';                                           // 정상
```

### 2.3 React 재고 상세 화면

- **수정 가능**: 안전재고 (Input), 상태 (Select)
- **적정재고(최대재고) 입력 필드 없음**

---

## 3. 변경 사항

### 3.1 DB 마이그레이션

```php
// API 마이그레이션 (stocks 테이블에 max_stock 추가)
Schema::table('stocks', function (Blueprint $table) {
    $table->decimal('max_stock', 15, 3)->default(0)
        ->comment('최대 재고 (적정재고 상한)')
        ->after('safety_stock');
});
```

### 3.2 Stock 모델 변경

```php
// fillable 추가
'max_stock',

// casts 추가
'max_stock' => 'decimal:3',

// calculateStatus() 확장
public function calculateStatus(): string
{
    if ($this->stock_qty <= 0) {
        return 'out';      // 재고 없음
    }
    if ($this->stock_qty < $this->safety_stock) {
        return 'low';      // 안전재고 미달
    }
    if ($this->max_stock > 0 && $this->stock_qty > $this->max_stock) {
        return 'over';     // 최대재고 초과
    }
    return 'normal';       // 정상 범위
}
```

> `max_stock = 0`이면 최대재고 미설정으로 간주 → 기존 동작과 동일 (하위 호환)

### 3.3 StockService 변경

`update()` 메서드에서 `max_stock` 필드 저장 추가.

### 3.4 API 응답 변경

`GET /api/v1/stocks/{id}` 응답에 `max_stock` 필드 추가.

`PUT /api/v1/stocks/{id}` 요청에 `max_stock` 필드 허용.

### 3.5 React 재고 상세 화면 변경

**수정 모드 기본 정보 카드 - Row 2 변경:**

| 현재 (4열) | 변경 후 (4열) |
|-----------|-------------|
| 규격 / 단위 / 재고량 / 안전재고 | 규격 / 단위 / 재고량 / 안전재고 |
| — | **Row 3 추가**: 최대재고 / 재공품 / 상태 / (빈칸) |

안전재고 라벨을 **"안전재고 (최소)"**, 최대재고는 **"최대재고"** 로 표시하여 적정재고 범위임을 직관적으로 전달.

**보기 모드도 동일하게 최대재고 필드 추가.**

### 3.6 재고 상태 표시 확장

| 상태 | 조건 | 라벨 | 색상 |
|------|------|------|------|
| `out` | stock_qty <= 0 | 없음 | 빨강 |
| `low` | stock_qty < safety_stock | 부족 | 주황 |
| `normal` | 범위 내 | 정상 | 초록 |
| `over` | stock_qty > max_stock (max_stock > 0) | 초과 | 보라 |

---

## 4. 검증 규칙

- `safety_stock >= 0` (필수)
- `max_stock >= 0` (필수, 0 = 미설정)
- `max_stock > 0`일 때 `max_stock >= safety_stock` (최대 >= 최소)
- 위반 시 저장 차단 + 에러 메시지

---

## 5. 영향 범위

| 대상 | 파일 | 변경 |
|------|------|------|
| DB | 마이그레이션 신규 | `max_stock` 컬럼 추가 |
| API 모델 | `Stock.php` | fillable, casts, calculateStatus |
| API 서비스 | `StockService.php` | update 로직에 max_stock 추가 |
| React 타입 | `types.ts` | `maxStock` 필드 추가 |
| React 액션 | `actions.ts` | updateStock에 max_stock 전달 |
| React UI | `StockStatusDetail.tsx` | 최대재고 입력 필드 + 상태 표시 |
| React 목록 | `StockStatusList.tsx` | `over` 상태 뱃지 추가 |

---

## 6. 하위 호환성

- `max_stock` 기본값 `0` → 미설정 시 기존 로직과 100% 동일
- 기존 `normal`/`low`/`out` 상태 그대로 유지
- `over` 상태는 `max_stock > 0`인 품목에서만 발생

---

## 관련 문서

- 재고 조정 위치 이동 요청: `plans/stock-detail-inventory-adjustment-request.md`
- 재고생산관리: `features/sales/stock-production.md`

---

**최종 업데이트**: 2026-03-20
