feat(item-management): Mock → API 연동 완료

Phase 2.3 자재관리 API 연동:
- actions.ts Mock 데이터 제거, 실제 API 연동
- 8개 API 함수 구현 (getItemList, getItemStats, getItem, createItem, updateItem, deleteItem, deleteItems, getCategoryOptions)
- 타입 변환 함수 구현 (Frontend ↔ Backend)
- 품목유형 매핑 (제품↔FG, 부품↔PT, 소모품↔CS, 공과↔RM)
- Frontend 전용 필터링 (specification, orderType, dateRange, sortBy)
This commit is contained in:
2026-01-09 16:58:50 +09:00
parent 749f0ce3c3
commit 5fa20c837a
3 changed files with 492 additions and 273 deletions

View File

@@ -0,0 +1,154 @@
# [IMPL-2026-01-09] 자재관리(품목관리) API 연동
## 작업 개요
- **작업자**: Claude Code
- **작업일**: 2026-01-09
- **Phase**: 2.3 자재관리 (시공사 페이지 API 연동 계획)
- **이전 Phase**: 2.2 거래처관리 완료
## 변경 사항 요약
### Backend (api/)
#### 1. 라우트 추가
**파일**: `routes/api.php`
```php
// Items (통합 품목 관리 - items 테이블)
Route::prefix('items')->group(function () {
Route::get('', [ItemsController::class, 'index'])->name('v1.items.index');
Route::get('/stats', [ItemsController::class, 'stats'])->name('v1.items.stats'); // 신규
Route::post('', [ItemsController::class, 'store'])->name('v1.items.store');
Route::get('/code/{code}', [ItemsController::class, 'showByCode'])->name('v1.items.show_by_code');
Route::get('/{id}', [ItemsController::class, 'show'])->name('v1.items.show');
Route::put('/{id}', [ItemsController::class, 'update'])->name('v1.items.update');
Route::delete('/batch', [ItemsController::class, 'batchDestroy'])->name('v1.items.batch_destroy');
Route::delete('/{id}', [ItemsController::class, 'destroy'])->name('v1.items.destroy');
});
```
**중요**: `/stats` 라우트는 `/{id}` 보다 먼저 정의하여 "stats"가 ID로 캡처되는 것을 방지
### Frontend (react/)
#### 1. actions.ts 완전 재작성
**파일**: `src/components/business/construction/item-management/actions.ts`
**변경 전**: Mock 데이터 기반 (mockItems, mockOrderItems 배열)
**변경 후**: 실제 API 연동
#### 주요 구현 내용
##### 타입 변환 함수
| 함수명 | 용도 |
|--------|------|
| `transformItemType()` | Backend item_type → Frontend itemType |
| `transformToBackendItemType()` | Frontend itemType → Backend item_type |
| `transformSpecification()` | Backend options → Frontend specification |
| `transformOrderType()` | Backend options → Frontend orderType |
| `transformStatus()` | Backend is_active + options → Frontend status |
| `transformOrderItems()` | Backend options → Frontend orderItems |
| `transformItem()` | API 응답 → Item 타입 |
| `transformItemDetail()` | API 응답 → ItemDetail 타입 |
| `transformItemToApi()` | ItemFormData → API 요청 데이터 |
##### 품목 유형 매핑
| Frontend (Korean) | Backend (Code) |
|-------------------|----------------|
| 제품 | FG |
| 부품 | PT |
| 소모품 | CS (또는 SM) |
| 공과 | RM |
##### API 함수
| 함수명 | API Endpoint | 설명 |
|--------|-------------|------|
| `getItemList()` | GET /api/v1/items | 품목 목록 조회 |
| `getItemStats()` | GET /api/v1/items/stats | 품목 통계 조회 |
| `getItem()` | GET /api/v1/items/{id} | 품목 상세 조회 |
| `createItem()` | POST /api/v1/items | 품목 등록 |
| `updateItem()` | PUT /api/v1/items/{id} | 품목 수정 |
| `deleteItem()` | DELETE /api/v1/items/{id} | 품목 삭제 |
| `deleteItems()` | DELETE /api/v1/items/batch | 품목 일괄 삭제 |
| `getCategoryOptions()` | GET /api/v1/categories | 카테고리 목록 조회 |
##### Frontend 전용 필터링
Backend에서 지원하지 않는 필터는 Frontend에서 처리:
- 규격 (specification) 필터
- 구분 (orderType) 필터
- 날짜 범위 (startDate, endDate) 필터
- 정렬 (sortBy: latest/oldest)
## 필드 매핑 상세
### Item 기본 필드
| Frontend | Backend | 변환 방식 |
|----------|---------|----------|
| id | id | String 변환 |
| itemNumber | code | 직접 매핑 |
| itemName | name | 직접 매핑 |
| itemType | item_type | transformItemType() |
| categoryId | category_id | String 변환 |
| categoryName | category.name | nested 접근 |
| unit | unit | 직접 매핑 (기본값: EA) |
| specification | options.specification | transformSpecification() |
| orderType | options.orderType | transformOrderType() |
| status | is_active + options.status | transformStatus() |
| createdAt | created_at | 직접 매핑 |
| updatedAt | updated_at | 직접 매핑 |
### ItemDetail 추가 필드
| Frontend | Backend | 변환 방식 |
|----------|---------|----------|
| note | description | 직접 매핑 |
| orderItems | options.orderItems | transformOrderItems() |
## 테스트 체크리스트
### API 연동 확인
- [ ] 품목 목록 조회 (GET /items)
- [ ] 품목 통계 조회 (GET /items/stats)
- [ ] 품목 상세 조회 (GET /items/{id})
- [ ] 품목 등록 (POST /items)
- [ ] 품목 수정 (PUT /items/{id})
- [ ] 품목 삭제 (DELETE /items/{id})
- [ ] 품목 일괄 삭제 (DELETE /items/batch)
- [ ] 카테고리 목록 조회 (GET /categories)
### 필터링 확인
- [ ] 검색 필터 (search → q)
- [ ] 품목유형 필터 (itemType → type)
- [ ] 카테고리 필터 (categoryId → category_id)
- [ ] 활성상태 필터 (status → active)
- [ ] 규격 필터 (Frontend only)
- [ ] 구분 필터 (Frontend only)
- [ ] 날짜 필터 (Frontend only)
### 데이터 변환 확인
- [ ] 품목유형 한글 ↔ 코드 변환
- [ ] 상태값 변환 (is_active ↔ status)
- [ ] options JSON 필드 파싱/생성
## 관련 파일
### 수정된 파일
1. `api/routes/api.php` - /items/stats 라우트 추가
2. `react/src/components/business/construction/item-management/actions.ts` - Mock → API 변환
### 참조 파일
- `api/app/Http/Controllers/Api/V1/ItemsController.php`
- `api/app/Services/ItemService.php`
- `react/src/components/business/construction/item-management/types.ts`
- `react/src/lib/api.ts`
## 다음 단계
### Phase 2.4 예정
- 자재관리 (품목관리) UI 컴포넌트 연동 테스트
- 에러 핸들링 개선
- 로딩 상태 처리
### 향후 개선 사항
- Backend에서 추가 필터 지원 시 Frontend 필터 제거
- options 필드 구조 표준화
- 품목 일괄 등록 API 추가 고려