⚙️ chore: Flyway 및 공통 API 응답 기반 구성#10
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe change adds shared API response and exception handling, enforces ChangesCommon API and infrastructure foundations
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/main/kotlin/com/zerost/api/common/config/WebMvcConfig.kt (1)
13-16: 🔒 Security & Privacy | 🔵 TrivialVerify that the interceptor is not being treated as an authentication boundary.
If
X-Device-Idbecomes security-sensitive, confirm that every relevant endpoint is handled by MVC and add tests for the registration path, trailing-slash variants, and any non-MVC endpoints. Spring recommends using the security filter chain for security enforcement rather than MVC interceptors. (docs.spring.io)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/kotlin/com/zerost/api/common/config/WebMvcConfig.kt` around lines 13 - 16, Review deviceIdInterceptor registration in addInterceptors and ensure it is used only for non-security concerns, not as an authentication or authorization boundary. If X-Device-Id is security-sensitive, move enforcement into the Spring Security filter chain and add coverage for registration, trailing-slash variants, and non-MVC endpoints.Source: MCP tools
src/main/kotlin/com/zerost/api/common/response/ApiResponse.kt (1)
23-28: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winMake
failure()generic for typed responses.ApiResponse.failure()is fixed toApiResponse<Nothing>, so it won’t compose with typed endpoints without a cast. Makingfailure()generic (or the wrapper covariant) keeps the shared response contract usable forApiResponse<T>handlers.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/kotlin/com/zerost/api/common/response/ApiResponse.kt` around lines 23 - 28, Update the ApiResponse.failure function to be generic over the response payload type and return ApiResponse<T> instead of ApiResponse<Nothing>, while preserving its unsuccessful status, null data, and supplied ApiErrorResponse. Ensure typed endpoint handlers can use failure without casts.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/kotlin/com/zerost/api/common/exception/GlobalExceptionHandler.kt`:
- Around line 46-58: Update handleMethodNotAllowed to preserve the Allow header
for 405 responses by copying ex.supportedHttpMethods into the ResponseEntity
headers, or delegate handling to Spring’s default resolver while retaining the
existing ApiResponse body and status.
- Around line 61-74: Update GlobalExceptionHandler.handleException so it does
not convert all exceptions into 500 responses. Extend
ResponseEntityExceptionHandler or add explicit handlers for Spring MVC 4xx
exceptions, including HandlerMethodValidationException,
HttpMessageNotReadableException, MissingServletRequestParameterException, and
MethodArgumentTypeMismatchException, while retaining the internal-server-error
response for genuine unhandled failures.
---
Nitpick comments:
In `@src/main/kotlin/com/zerost/api/common/config/WebMvcConfig.kt`:
- Around line 13-16: Review deviceIdInterceptor registration in addInterceptors
and ensure it is used only for non-security concerns, not as an authentication
or authorization boundary. If X-Device-Id is security-sensitive, move
enforcement into the Spring Security filter chain and add coverage for
registration, trailing-slash variants, and non-MVC endpoints.
In `@src/main/kotlin/com/zerost/api/common/response/ApiResponse.kt`:
- Around line 23-28: Update the ApiResponse.failure function to be generic over
the response payload type and return ApiResponse<T> instead of
ApiResponse<Nothing>, while preserving its unsuccessful status, null data, and
supplied ApiErrorResponse. Ensure typed endpoint handlers can use failure
without casts.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 73488dc3-b8ad-4ba4-be96-108ff0e31c15
📒 Files selected for processing (12)
build.gradle.ktssrc/main/kotlin/com/zerost/api/common/config/SecurityConfig.ktsrc/main/kotlin/com/zerost/api/common/config/WebMvcConfig.ktsrc/main/kotlin/com/zerost/api/common/device/DeviceConstants.ktsrc/main/kotlin/com/zerost/api/common/device/DeviceIdInterceptor.ktsrc/main/kotlin/com/zerost/api/common/exception/BusinessException.ktsrc/main/kotlin/com/zerost/api/common/exception/ErrorCode.ktsrc/main/kotlin/com/zerost/api/common/exception/GlobalExceptionHandler.ktsrc/main/kotlin/com/zerost/api/common/response/ApiErrorResponse.ktsrc/main/kotlin/com/zerost/api/common/response/ApiResponse.ktsrc/main/resources/application-test.ymlsrc/main/resources/application.yaml
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/kotlin/com/zerost/api/common/exception/GlobalExceptionHandler.kt (1)
88-101: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winNarrow the
RuntimeExceptionfallback.An application-defined
RuntimeExceptionannotated with@ResponseStatuscan be converted to this 500 response instead of retaining its declared status. Restrict this handler to an application-specific unexpected-exception type, or explicitly preserve status-bearing exceptions. Spring defines@ResponseStatusas an exception-to-status mapping. (docs.spring.io)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/kotlin/com/zerost/api/common/exception/GlobalExceptionHandler.kt` around lines 88 - 101, Update handleRuntimeException in GlobalExceptionHandler so the fallback does not catch application RuntimeExceptions carrying `@ResponseStatus`; narrow it to the project’s unexpected-exception type, or explicitly bypass status-bearing exceptions so Spring can apply their declared status. Preserve the existing 500 ApiResponse behavior for genuinely unexpected runtime failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/kotlin/com/zerost/api/common/exception/GlobalExceptionHandler.kt`:
- Around line 54-86: Update handleExceptionInternal so every supported 4xx
status, including 404, 406, and 415, produces an ApiErrorResponse with the
corresponding status-specific ErrorCode instead of INTERNAL_SERVER_ERROR. Add
the necessary ErrorCode mappings or preserve the exception’s status-aware
response body, and add tests covering these MVC error statuses.
- Around line 54-86: Update handleExceptionInternal to preserve Spring’s
already-committed-response guard by delegating through
super.handleExceptionInternal with the constructed response, or by checking
response.isCommitted before constructing and returning the API error. Keep the
existing status-based response mapping for uncommitted responses.
---
Outside diff comments:
In `@src/main/kotlin/com/zerost/api/common/exception/GlobalExceptionHandler.kt`:
- Around line 88-101: Update handleRuntimeException in GlobalExceptionHandler so
the fallback does not catch application RuntimeExceptions carrying
`@ResponseStatus`; narrow it to the project’s unexpected-exception type, or
explicitly bypass status-bearing exceptions so Spring can apply their declared
status. Preserve the existing 500 ApiResponse behavior for genuinely unexpected
runtime failures.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 8014b6b8-0d87-49b0-bf5b-2d108826ee64
📒 Files selected for processing (1)
src/main/kotlin/com/zerost/api/common/exception/GlobalExceptionHandler.kt
#️⃣ Issue Number
📝 요약(Summary)
X-Device-Id헤더를 공통 계층에서 검증하도록 Interceptor를 추가하고, 유저 등록 API를 제외한 요청에 공통 규칙이 적용되도록 구성했습니다.📝 리뷰 요청사항
X-Device-Id검증은 컨트롤러마다 반복하지 않고 Interceptor에서 공통 처리하도록 구성했습니다.permitAll()로 열고, API 공통 규칙은 MVC 계층에서 우선 강제하도록 분리했습니다.💻 테스트 결과
./gradlew -q compileKotlin기준으로 공통 응답/예외 처리 및 디바이스 헤더 처리 코드가 정상 컴파일되는지 확인했습니다.X-Device-Id누락 시 공통 예외 응답으로 처리되는 구조를 코드 기준으로 반영했습니다./api/v1/users/register)는 헤더 검증 대상에서 제외되도록 설정했습니다.📌 포인트
✍️ 회고
✅ 리뷰 반영
Allow헤더 손실 가능성과 광역 예외 처리로 인한 4xx → 500 변환 가능성을 확인했습니다.ResponseEntityExceptionHandler기반으로 조정해 Spring MVC 기본 상태 매핑을 유지하도록 보완했습니다.Summary by CodeRabbit
New Features
X-Device-Id(available for downstream processing).Bug Fixes
X-Device-Idnow returns a clear client error.Chores / Infrastructure