From f452ec94db8823861e1d5c1fd89587d62ad4fffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Sat, 14 Mar 2026 16:39:57 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20[changes]=20=EC=9A=B4=EC=98=81=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=95=88=EC=A0=84=EC=84=B1=20=EA=B2=80?= =?UTF-8?q?=ED=86=A0=20=EA=B2=B0=EA=B3=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 수정 2개 파일의 동작 동등성 검증 (수정 전 = 수정 후) - 엣지 케이스 5건 검증 (null, 빈 배열, 없는 ID 등) - 전체 256개 테스트 결과, 수정으로 인한 실패 0건 확인 - 기존 문제 발견: process_items tenant_id 필터 누락 --- ...20260314_api_quality_improvement_deploy.md | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/dev/changes/20260314_api_quality_improvement_deploy.md b/dev/changes/20260314_api_quality_improvement_deploy.md index a97a9a1..832a5f2 100644 --- a/dev/changes/20260314_api_quality_improvement_deploy.md +++ b/dev/changes/20260314_api_quality_improvement_deploy.md @@ -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개 테스트 호환 확인