From 24d99add5853216491717e4aac1cd782bd7cf49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Thu, 19 Mar 2026 10:38:39 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20[changes]=20=ED=92=88=EB=AA=A9=EA=B8=B0?= =?UTF-8?q?=EC=A4=80=EA=B4=80=EB=A6=AC=20=ED=95=84=EB=93=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20422=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- INDEX.md | 1 + ...260319_item_master_field_validation_fix.md | 77 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 changes/20260319_item_master_field_validation_fix.md diff --git a/INDEX.md b/INDEX.md index 24ff253..84be23f 100644 --- a/INDEX.md +++ b/INDEX.md @@ -277,6 +277,7 @@ DB 도메인별: | [20260319_item_master_field_search.md](changes/20260319_item_master_field_search.md) | 서비스 품목기준관리 항목 탭 검색 기능 추가 | | [20260319_nonconforming_management_api.md](changes/20260319_nonconforming_management_api.md) | 부적합관리 API 구현 (8개 엔드포인트 + 결재 연동) | | [20260319_statcards_grid_layout_fix.md](changes/20260319_statcards_grid_layout_fix.md) | StatCards 카드 6개 한 행 표시 개선 | +| [20260319_item_master_field_validation_fix.md](changes/20260319_item_master_field_validation_fix.md) | 품목기준관리 필드 수정 422 유효성 검증 오류 수정 | --- diff --git a/changes/20260319_item_master_field_validation_fix.md b/changes/20260319_item_master_field_validation_fix.md new file mode 100644 index 0000000..66c9158 --- /dev/null +++ b/changes/20260319_item_master_field_validation_fix.md @@ -0,0 +1,77 @@ +# 품목기준관리 필드 수정 422 유효성 검증 오류 수정 + +**날짜:** 2026-03-19 +**작업자:** Claude Code + +## 변경 개요 + +품목기준관리(Item Master) 필드 수정 시 `PUT /api/v1/item-master/fields/{id}` 요청에서 422 유효성 검증 오류가 발생하는 문제를 수정했다. 두 가지 원인이 있었다: + +1. **field_key regex 불일치**: 기존 데이터 39건이 숫자로 시작하는 `field_key` (예: `101_specification_1`)를 사용하지만, FormRequest의 regex가 영문자 시작만 허용 +2. **422 응답 포맷 불일치**: API의 Handler.php와 ApiResponse::handle이 서로 다른 에러 포맷을 사용하여, 프론트엔드에서 validation 에러 상세 정보를 받지 못함 + +--- + +## 수정된 파일 + +### API (`sam/api`) + +| 파일 | 변경 내용 | +|------|----------| +| `app/Exceptions/Handler.php` | 422 응답에 `errors` 최상위 필드 추가 (기존 `error.details`와 병행) | +| `app/Http/Requests/ItemMaster/ItemFieldUpdateRequest.php` | `field_key` regex: `^[a-zA-Z]` → `^[a-zA-Z0-9]` | +| `app/Http/Requests/ItemMaster/ItemFieldStoreRequest.php` | 동일 regex 수정 | +| `app/Http/Requests/ItemMaster/IndependentFieldStoreRequest.php` | 동일 regex 수정 | + +### React (`sam/react`) — FE 개발자 반영 필요 + +| 파일 | 변경 내용 | +|------|----------| +| `src/lib/api/error-handler.ts` | 422 에러 시 `data.errors \|\| data.error?.details` 폴백 추가 | + +--- + +## 상세 변경 사항 + +### 1. field_key regex 완화 + +``` +변경 전: /^[a-zA-Z][a-zA-Z0-9_]*$/ (영문자 시작 필수) +변경 후: /^[a-zA-Z0-9][a-zA-Z0-9_]*$/ (영문자 또는 숫자 시작 허용) +``` + +기존 데이터 39건이 `100_item_name`, `101_specification_1` 등 숫자로 시작하는 `field_key`를 사용하고 있어 regex를 완화했다. + +### 2. Handler.php 422 응답 포맷 통일 + +``` +변경 전 (Handler.php): +{ "success": false, "message": "입력값 검증 실패", "error": { "code": 422, "details": {...} } } + +변경 후 (Handler.php): +{ "success": false, "message": "입력값 검증 실패", "errors": {...}, "error": { "code": 422, "details": {...} } } +``` + +`errors` 최상위 필드를 추가하여 `ApiResponse::handle`의 포맷과 통일했다. 기존 `error.details` 구조는 하위호환을 위해 유지한다. + +### 3. React error-handler 폴백 + +```typescript +// 변경 전 +data.errors // Handler.php 경유 시 undefined + +// 변경 후 +data.errors || data.error?.details // 양쪽 포맷 모두 지원 +``` + +--- + +## 테스트 체크리스트 + +- [x] field_key가 숫자로 시작하는 필드(ID 315) 수정 요청 정상 처리 +- [x] 422 에러 시 프론트엔드에서 validation 에러 상세 표시 +- [ ] 개발서버 배포 후 품목기준관리 필드 수정 동작 확인 + +--- + +**최종 업데이트**: 2026-03-19