docs: [changes] 운영 코드 안전성 검토 결과 추가

- 수정 2개 파일의 동작 동등성 검증 (수정 전 = 수정 후)
- 엣지 케이스 5건 검증 (null, 빈 배열, 없는 ID 등)
- 전체 256개 테스트 결과, 수정으로 인한 실패 0건 확인
- 기존 문제 발견: process_items tenant_id 필터 누락
This commit is contained in:
김보곤
2026-03-14 16:39:57 +09:00
parent b6edc6db27
commit f452ec94db

View File

@@ -231,6 +231,77 @@ foreach ($bendingItems as $item) {
---
## 4. 운영 코드 안전성 검토
배포 후 수정된 운영 코드(테스트 파일 제외)가 기존 API 동작에 영향을 미치는지 코드 리뷰 + 전체 테스트로 검증했다.
### 4.1 검토 대상
실제 운영 코드를 수정한 파일은 **2개뿐**이다. 나머지 22개는 모두 테스트/Factory 파일이다.
| 파일 | 수정 메서드 | 수정 내용 |
|------|-----------|----------|
| `WorkOrderService.php` | `getMaterials()` | BOM 루프 내 `find()` → 배치 사전 로드 |
| `OrderService.php` | `createWorkOrderFromOrder()` | fallback 루프 내 DB 쿼리 → 배치 사전 조회 |
| `OrderService.php` | `checkBendingStockForOrder()` | StockService 루프 호출 → 배치 조회 |
### 4.2 동작 동등성 검증 (수정 전 = 수정 후)
| 수정 | 판정 | 근거 |
|------|:----:|------|
| `getMaterials()` BOM 배치 | **동등** | null 처리, 빈 배열, BOM 없는 경우 모두 동일. `$bomItemsMap[$id] ?? null``find($id)`와 동일한 null 반환 |
| `createWorkOrderFromOrder()` fallback | **동등** | 사전 배치 조회 결과가 즉석 조회와 동일. `DB::transaction` 내부이므로 중간 데이터 변경 없음. 캐시(`codeToIdMap`) 동작도 동일 |
| `checkBendingStockForOrder()` Stock | **동등** | `Stock::whereIn()` 결과가 `StockService::getAvailableStock()` 결과와 동일. `BelongsToTenant` 스코프 + 명시적 `tenant_id` 조건으로 격리 보장 |
### 4.3 엣지 케이스 검증
| 케이스 | 수정 전 | 수정 후 | 동일? |
|--------|--------|--------|:-----:|
| `item_id`가 null인 품목 | `if ($woItem->item_id)` skip | 맵에 포함되지 않아 동일하게 skip | ✅ |
| BOM JSON이 비어있는 품목 | `empty($item->bom)` skip | 동일 | ✅ |
| DB에 없는 `item_code` | `find()` → null | `$map[$code] ?? null` → null | ✅ |
| 재고가 0인 품목 | Stock 없음 → available_qty=0 | `$stocksMap->get($id)` → null → 0 | ✅ |
| 빈 주문 (items 0건) | 루프 미실행 | 배치 조회도 빈 배열, 루프 미실행 | ✅ |
### 4.4 전체 테스트 실행 결과
```
PHPUnit 11.5.27 / PHP 8.4.18
전체: 256개 테스트 실행
통과: 243개
실패: 7개 (모두 수정 전부터 존재하던 기존 문제)
Skip: 6개
이번 수정으로 인한 실패: 0건
```
**실패 7건 상세 (모두 기존 문제):**
| 테스트 | 원인 | 이번 수정과 관계 |
|--------|------|:--------------:|
| `PrefixResolverTest` (1건) | Unit 로직 불일치 (XX vs CF) | 무관 |
| `BendingLotPipelineTest` (3건) | TENANT_ID=287 고정, 로컬 DB 데이터 없음 | 무관 |
| `ItemMasterApiTest` (3건) | `section_id` 컬럼 미존재 (마이그레이션 불일치) | 무관 |
### 4.5 발견된 기존 문제 (수정과 무관, 별도 대응 필요)
`process_items` 테이블 조회에 `tenant_id` 필터가 없다. 수정 전부터 존재하던 문제이며 이번 수정으로 악화되지 않았다. 멀티테넌트 격리가 필요하면 별도 수정이 필요하다.
```php
// OrderService.php — tenant_id 조건 누락 (수정 전/후 동일)
DB::table('process_items')
->whereIn('item_id', $ids)
->where('is_active', true) // tenant_id 없음
->get();
```
### 4.6 결론
**이번 수정으로 기존 API 동작이 깨지는 경우는 없다.** 수정 전과 후의 결과가 정확히 동일하며, 쿼리 수만 줄어든 순수 성능 개선이다.
---
## 테스트 체크리스트
- [x] TestCase 공통 헬퍼 작성 및 기존 11개 테스트 호환 확인