From 0a2dfb9f589358b74b2b288f90636da89fd1571c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Tue, 17 Mar 2026 20:43:45 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20[stock]=20=EC=9E=AC=EA=B3=A0=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=95=20=EC=9A=94=EC=B2=AD=EC=84=9C=20API=20?= =?UTF-8?q?=EC=8A=A4=ED=8E=99=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - API 구현 완료 반영 (GET/POST /stocks/{id}/adjustments) - 요청/응답 JSON 예시 추가 - TypeScript 타입 정의 및 Server Action 예시 추가 --- ...ock-detail-inventory-adjustment-request.md | 171 ++++++++++++++---- 1 file changed, 139 insertions(+), 32 deletions(-) diff --git a/plans/stock-detail-inventory-adjustment-request.md b/plans/stock-detail-inventory-adjustment-request.md index c886d82..ace860a 100644 --- a/plans/stock-detail-inventory-adjustment-request.md +++ b/plans/stock-detail-inventory-adjustment-request.md @@ -3,6 +3,7 @@ **날짜:** 2026-03-17 **요청자:** R&D실 (백엔드) **대상:** React 프론트엔드 +**API 상태:** 구현 완료 --- @@ -37,7 +38,7 @@ │ └─ 재공품, 상태 │ └─ 재고 조정 섹션 ← 기본 정보 바로 아래에 추가 - ├─ 이력 테이블 (No, 조정일시, 증감 수량, 검수자) + ├─ 이력 테이블 (No, 조정일시, 증감 수량, 사유, 검수자) └─ + 추가 버튼 ``` @@ -62,7 +63,7 @@ | 파일 | 설명 | |------|------| -| `ReceivingManagement/InventoryAdjustmentDialog.tsx` | 재고 조정 다이얼로그 (이동 또는 공통 위치로 추출) | +| `ReceivingManagement/InventoryAdjustmentDialog.tsx` | 재고 조정 다이얼로그 (공통 위치로 추출 권장) | --- @@ -71,16 +72,16 @@ ### 이력 테이블 ``` -┌──────────────────────────────────────────────────────────┐ -│ 재고 조정 [+ 추가] │ -├──────────────────────────────────────────────────────────┤ -│ No │ 조정일시 │ 증감 수량 │ 검수자 │ -├──────┼─────────────────────┼────────────┼───────────────┤ -│ 1 │ 2026-03-17 14:30 │ +100 │ 김보곤 │ -│ 2 │ 2026-03-16 10:15 │ -50 │ 홍길동 │ -├──────────────────────────────────────────────────────────┤ -│ 재고 조정 이력이 없습니다. │ -└──────────────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────────────────────┐ +│ 재고 조정 [+ 추가] │ +├──────────────────────────────────────────────────────────────────┤ +│ No │ 조정일시 │ 증감 수량 │ 사유 │ 검수자 │ +├──────┼─────────────────────┼────────────┼─────────┼────────────┤ +│ 1 │ 2026-03-17 14:30 │ +100 │ 실사조정 │ 김보곤 │ +│ 2 │ 2026-03-16 10:15 │ -50 │ 파손폐기 │ 홍길동 │ +├──────────────────────────────────────────────────────────────────┤ +│ 재고 조정 이력이 없습니다. │ +└──────────────────────────────────────────────────────────────────┘ ``` ### 컬럼 정의 @@ -88,37 +89,143 @@ | 컬럼 | 필드 | 설명 | |------|------|------| | No | (순번) | 행 번호 | -| 조정일시 | `adjusted_at` | 조정 시각 (YYYY-MM-DD HH:mm) | +| 조정일시 | `adjusted_at` | 조정 시각 (`YYYY-MM-DD HH:mm`) | | 증감 수량 | `quantity` | 양수(+): 증가, 음수(-): 감소 | -| 검수자 | `inspector` | 조정 승인자 이름 | +| 사유 | `remark` | 조정 사유 (nullable) | +| 검수자 | `inspector` | 조정 수행자 이름 | ### + 추가 버튼 동작 -1. 클릭 시 `InventoryAdjustmentDialog` 모달 오픈 -2. 증감 수량 및 사유 입력 -3. 저장 시 API 호출 → 이력 테이블에 신규 행 추가 -4. 재고량 자동 갱신 (기본 정보의 재고량 반영) +1. 클릭 시 간단한 입력 폼 또는 모달 오픈 +2. **증감 수량** (필수, 0 제외) 및 **사유** (선택) 입력 +3. 저장 시 `POST /api/v1/stocks/{stockId}/adjustments` 호출 +4. 성공 시 이력 테이블 새로고침 + 기본 정보의 재고량 갱신 --- -## API 엔드포인트 +## API 엔드포인트 (구현 완료) -> 현재 재고 조정 API가 미구현 상태. 백엔드에서 구현 예정. - -### 예상 엔드포인트 +### 1. 재고 조정 이력 조회 ``` -GET /api/v1/stocks/{id}/adjustments - → 해당 재고의 조정 이력 조회 - → 응답: { data: InventoryAdjustmentRecord[] } - -POST /api/v1/stocks/{id}/adjustments - → 재고 조정 등록 - → 요청: { quantity: number, remark?: string } - → 응답: { data: { id, adjusted_at, quantity, inspector, ... } } +GET /api/v1/stocks/{stockId}/adjustments ``` -> API 구현 완료 후 별도 안내 예정. 우선 UI 배치 작업을 진행해주세요. +**응답:** + +```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), + }); +} +``` --- @@ -127,4 +234,4 @@ POST /api/v1/stocks/{id}/adjustments - 재고 상세 화면: `/material/stock-status/{id}` - 기존 재고 조정 컴포넌트: `ReceivingManagement/InventoryAdjustmentDialog.tsx` - 재고 상세 컴포넌트: `StockStatus/StockStatusDetail.tsx` -- 채번규칙 문서: `docs/rules/numbering-rules.md` +- API 커밋: `feat: [stock] 재고 조정 API 추가`