# 재고 조정 위치 이동 요청 — 입고관리 → 재고 상세

**날짜:** 2026-03-17
**요청자:** R&D실 (백엔드)
**대상:** React 프론트엔드
**API 상태:** 구현 완료

---

## 변경 요약

**재고 조정** 기능을 입고관리 화면에서 분리하여 **재고현황 > 재고 상세** 화면으로 이동한다.

---

## 현재 구조 (AS-IS)

```
입고관리 목록 (ReceivingList.tsx)
  → 헤더에 [재고 조정] 버튼 → InventoryAdjustmentDialog 팝업

입고관리 상세 (ReceivingDetail.tsx)
  → 하단에 재고 조정 이력 섹션
```

**문제**: 재고 조정은 특정 입고 건과 무관하게 품목 재고를 직접 증감하는 기능이므로, 입고관리보다 재고현황에 위치하는 것이 적합하다.

---

## 변경 구조 (TO-BE)

```
재고현황 (/material/stock-status)
└─ 재고 상세 (/material/stock-status/{id})
   ├─ 기본 정보 (기존)
   │   ├─ 자재번호, 품목코드, 품목유형, 품목명
   │   ├─ 규격, 단위, 재고량, 안전재고
   │   └─ 재공품, 상태
   │
   └─ 재고 조정 섹션 ← 기본 정보 바로 아래에 추가
       ├─ 이력 테이블 (No, 조정일시, 증감 수량, 사유, 검수자)
       └─ + 추가 버튼
```

---

## 대상 컴포넌트

### 제거 (입고관리)

| 파일 | 변경 |
|------|------|
| `ReceivingManagement/ReceivingList.tsx` | 헤더의 "재고 조정" 버튼 + `isAdjustmentOpen` 상태 + `InventoryAdjustmentDialog` 제거 |
| `ReceivingManagement/ReceivingDetail.tsx` | 재고 조정 이력 섹션 렌더링 제거 |
| `ReceivingManagement/types.ts` | `InventoryAdjustmentRecord` 타입은 유지 (공유) 또는 이동 |

### 추가 (재고 상세)

| 파일 | 변경 |
|------|------|
| `StockStatus/StockStatusDetail.tsx` | 기본 정보 카드 아래에 재고 조정 섹션 추가 |

### 재사용

| 파일 | 설명 |
|------|------|
| `ReceivingManagement/InventoryAdjustmentDialog.tsx` | 재고 조정 다이얼로그 (공통 위치로 추출 권장) |

---

## 재고 조정 섹션 UI 명세

### 이력 테이블

```
┌──────────────────────────────────────────────────────────────────┐
│  재고 조정                                          [+ 추가]     │
├──────────────────────────────────────────────────────────────────┤
│  No  │  조정일시           │  증감 수량  │  사유    │  검수자     │
├──────┼─────────────────────┼────────────┼─────────┼────────────┤
│  1   │  2026-03-17 14:30   │  +100      │  실사조정 │  김보곤    │
│  2   │  2026-03-16 10:15   │  -50       │  파손폐기 │  홍길동    │
├──────────────────────────────────────────────────────────────────┤
│               재고 조정 이력이 없습니다.                           │
└──────────────────────────────────────────────────────────────────┘
```

### 컬럼 정의

| 컬럼 | 필드 | 설명 |
|------|------|------|
| No | (순번) | 행 번호 |
| 조정일시 | `adjusted_at` | 조정 시각 (`YYYY-MM-DD HH:mm`) |
| 증감 수량 | `quantity` | 양수(+): 증가, 음수(-): 감소 |
| 사유 | `remark` | 조정 사유 (nullable) |
| 검수자 | `inspector` | 조정 수행자 이름 |

### + 추가 버튼 동작

1. 클릭 시 간단한 입력 폼 또는 모달 오픈
2. **증감 수량** (필수, 0 제외) 및 **사유** (선택) 입력
3. 저장 시 `POST /api/v1/stocks/{stockId}/adjustments` 호출
4. 성공 시 이력 테이블 새로고침 + 기본 정보의 재고량 갱신

---

## API 엔드포인트 (구현 완료)

### 1. 재고 조정 이력 조회

```
GET /api/v1/stocks/{stockId}/adjustments
```

**응답:**

```json
{
  "success": true,
  "message": "데이터를 조회했습니다.",
  "data": [
    {
      "id": 1,
      "adjusted_at": "2026-03-17 14:30",
      "quantity": 100,
      "balance_qty": 196,
      "remark": "실사 조정",
      "inspector": "김보곤"
    },
    {
      "id": 2,
      "adjusted_at": "2026-03-16 10:15",
      "quantity": -50,
      "balance_qty": 96,
      "remark": "파손 폐기",
      "inspector": "홍길동"
    }
  ]
}
```

> `stockId`는 재고 상세 조회(`GET /api/v1/stocks/{id}`)에서 받는 `stock.id` 값이다.

### 2. 재고 조정 등록

```
POST /api/v1/stocks/{stockId}/adjustments
```

**요청:**

```json
{
  "quantity": 100,
  "remark": "실사 조정"
}
```

| 필드 | 타입 | 필수 | 설명 |
|------|------|:----:|------|
| `quantity` | number | O | 증감 수량 (양수: 증가, 음수: 감소, 0 불가) |
| `remark` | string | X | 조정 사유 (최대 500자) |

**응답:**

```json
{
  "success": true,
  "message": "데이터를 생성했습니다.",
  "data": {
    "id": 3,
    "adjusted_at": "2026-03-17 15:00",
    "quantity": 100,
    "balance_qty": 296,
    "remark": "실사 조정",
    "inspector": "김보곤"
  }
}
```

### 3. stockId 확인 방법

재고 상세 조회 응답에서 `stock` 관계의 `id`를 사용한다:

```
GET /api/v1/stocks/{itemId}   ← 이것은 Item ID
→ response.data.stock.id     ← 이것이 stockId (adjustments에 사용)
```

---

## TypeScript 타입 정의

```typescript
interface StockAdjustmentRecord {
  id: number;
  adjusted_at: string;    // "2026-03-17 14:30"
  quantity: number;        // 양수: 증가, 음수: 감소
  balance_qty: number;     // 조정 후 잔량
  remark: string | null;   // 조정 사유
  inspector: string;       // 검수자 이름
}

interface StockAdjustmentForm {
  quantity: number;        // 필수, 0 불가
  remark?: string;         // 선택, 최대 500자
}
```

---

## Server Action 예시

```typescript
// actions.ts에 추가
export async function getStockAdjustments(stockId: number) {
  return fetchApi(`/stocks/${stockId}/adjustments`);
}

export async function createStockAdjustment(
  stockId: number,
  data: StockAdjustmentForm
) {
  return fetchApi(`/stocks/${stockId}/adjustments`, {
    method: 'POST',
    body: JSON.stringify(data),
  });
}
```

---

## 참고

- 재고 상세 화면: `/material/stock-status/{id}`
- 기존 재고 조정 컴포넌트: `ReceivingManagement/InventoryAdjustmentDialog.tsx`
- 재고 상세 컴포넌트: `StockStatus/StockStatusDetail.tsx`
- API 커밋: `feat: [stock] 재고 조정 API 추가`
