feat : 서버 점검 상태 확인 API 및 필터를 통해 점검 시 API 호출 차단 로직 추가#75
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
Walkthrough서버 유지보수 상태 기능을 추가합니다. 유지보수 상태를 관리하는 도메인·서비스·레포지토리·컨트롤러와 요청을 차단하는 MaintenanceFilter, SecurityConfig 연동 및 관련 단위 테스트가 포함됩니다. Changes
Sequence DiagramsequenceDiagram
participant Client
participant MaintenanceFilter
participant MaintenanceService
participant MaintenanceRepository
participant Database as DB
Client->>MaintenanceFilter: HTTP 요청 (URI)
MaintenanceFilter->>MaintenanceService: isMaintenanceInProgress()
MaintenanceService->>MaintenanceRepository: findById(DEFAULT_ID)
MaintenanceRepository->>Database: SELECT maintenance
Database-->>MaintenanceRepository: Maintenance or null
MaintenanceRepository-->>MaintenanceService: Maintenance?
alt 유지보수 중 && 비화이트리스트
MaintenanceService-->>MaintenanceFilter: true
MaintenanceFilter->>MaintenanceFilter: isWhitelisted(URI) -> false
MaintenanceFilter->>Client: 503 JSON (MAINTENANCE_IN_PROGRESS)
else 화이트리스트 또는 정상 상태
MaintenanceService-->>MaintenanceFilter: false or 화이트리스트
MaintenanceFilter->>Client: 요청 통과 (다음 필터/핸들러)
end
sequenceDiagram
participant Admin
participant MaintenanceController
participant MaintenanceService
participant MaintenanceRepository
participant Database as DB
Admin->>MaintenanceController: PATCH /api/v1/maintenance/status (request)
MaintenanceController->>MaintenanceService: updateStatus(request)
MaintenanceService->>MaintenanceRepository: findById(DEFAULT_ID)
MaintenanceRepository->>Database: SELECT maintenance
Database-->>MaintenanceRepository: Maintenance or null
alt 기존 항목 존재
MaintenanceService->>MaintenanceService: maintenance.update(status,message)
else 신규 항목
MaintenanceService->>MaintenanceService: Maintenance.initialize(status,message)
end
MaintenanceService->>MaintenanceRepository: save(maintenance)
MaintenanceRepository->>Database: INSERT/UPDATE
Database-->>MaintenanceRepository: 저장 완료
MaintenanceRepository-->>MaintenanceService: saved Maintenance
MaintenanceService-->>MaintenanceController: MaintenanceStatusResponse
MaintenanceController-->>Admin: 200 JSON 응답
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (1)
src/main/java/com/gpt/geumpumtabackend/maintenance/service/MaintenanceService.java (1)
21-25: 생성 케이스에서 상태/메시지 할당이 중복됩니다.
orElseGet에서 이미 요청값으로 생성하고 있어 바로 아래maintenance.update(...)가 신규 생성 흐름에서는 중복입니다. 기본값으로 생성 후 update 1회로 통일하면 의도가 더 분명해집니다.♻️ 정리 예시
public MaintenanceStatusResponse updateStatus(MaintenanceStatusUpdateRequest request) { Maintenance maintenance = maintenanceRepository.findById(Maintenance.DEFAULT_ID) - .orElseGet(() -> Maintenance.initialize(request.status(), request.message())); + .orElseGet(() -> Maintenance.initialize(ServiceStatus.NORMAL, null)); maintenance.update(request.status(), request.message()); return MaintenanceStatusResponse.from(maintenanceRepository.save(maintenance)); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/gpt/geumpumtabackend/maintenance/service/MaintenanceService.java` around lines 21 - 25, The code currently constructs a new Maintenance with request values inside maintenanceRepository.findById(...).orElseGet(() -> Maintenance.initialize(request.status(), request.message())) and then immediately calls maintenance.update(request.status(), request.message()), causing duplicate assignment on creation; change the orElseGet to create a default/empty Maintenance (e.g. use Maintenance.initialize() or another no-arg initializer) so that you always obtain a maintenance instance and then call maintenance.update(request.status(), request.message()) exactly once; reference the Maintenance.initialize(...) call and the maintenance.update(...) invocation to locate and modify the creation path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/java/com/gpt/geumpumtabackend/global/exception/ExceptionType.java`:
- Line 79: The enum entry MAINTENANCE_IN_PROGRESS in ExceptionType uses an
invalid prefix "MT001"; update its error code to follow the allowed prefixes
(e.g., change "MT001" to a valid M-prefixed code such as "M001" or another
unique M... value) so it conforms to the ExceptionType prefix convention; ensure
the new code is unique within ExceptionType and update any references to
MAINTENANCE_IN_PROGRESS if they rely on the old string.
In
`@src/main/java/com/gpt/geumpumtabackend/global/maintenance/MaintenanceFilter.java`:
- Around line 45-48: The filter currently uses request.getRequestURI() which
includes the context path and can break whitelist matching; in MaintenanceFilter
replace usage of getRequestURI() with request.getServletPath() (used where
requestUri is assigned) so isWhitelisted(...) compares the servlet path, and
keep existing logic around isWhitelisted(...) and
maintenanceService.isMaintenanceInProgress() before calling
filterChain.doFilter(...); after the change, run or add tests that simulate a
non-empty context-path to ensure isWhitelisted(String) still matches expected
paths.
In `@src/main/java/com/gpt/geumpumtabackend/maintenance/domain/Maintenance.java`:
- Around line 13-16: Add the soft-delete SQL behavior to the Maintenance entity
by annotating the Maintenance class with `@SQLDelete` using an UPDATE statement
that sets deleted_at = NOW() for the row with the given id (follow the same
pattern used in the User entity); locate the Maintenance class declaration
(public class Maintenance extends BaseEntity) and add the `@SQLDelete`(...)
annotation above it and consider masking any sensitive fields on delete if your
User pattern does so.
In
`@src/test/java/com/gpt/geumpumtabackend/unit/global/maintenance/MaintenanceFilterTest.java`:
- Around line 22-24: The test class MaintenanceFilterTest currently does not
extend the project's unit test base; modify the class declaration so
MaintenanceFilterTest extends BaseUnitTest to comply with the
JUnit5+Mockito+AssertJ convention used across tests; locate the class named
MaintenanceFilterTest and update its signature to inherit from BaseUnitTest (and
add any missing import for BaseUnitTest) so the test uses the shared
setup/teardown and utilities provided by BaseUnitTest.
In
`@src/test/java/com/gpt/geumpumtabackend/unit/maintenance/service/MaintenanceServiceTest.java`:
- Around line 23-25: The test class MaintenanceServiceTest must extend the
project test base; update the class declaration to extend BaseUnitTest (i.e.,
change "class MaintenanceServiceTest" to "class MaintenanceServiceTest extends
BaseUnitTest") and adjust imports/annotations as needed (for example remove or
keep `@ExtendWith`(MockitoExtension.class) only if BaseUnitTest already configures
Mockito/JUnit extensions) so the file conforms to the unit test base class rule.
- Around line 33-69: Add unit tests to cover exception and boundary scenarios
around MaintenanceService.updateStatus: include tests that pass a null message
and an empty message in MaintenanceStatusUpdateRequest to assert expected
handling (e.g., message stored as null/empty or validation exception), a test
for invalid or disallowed status transitions (if business rules exist) by
invoking updateStatus with such transitions and asserting the thrown exception
or no-op, and tests that simulate repository failures by stubbing
maintenanceRepository.save(...) to throw an exception to verify error handling;
locate these in MaintenanceServiceTest and use the existing patterns
(Maintenance.initialize, MaintenanceStatusUpdateRequest, maintenanceRepository
mocks, and verify calls) or add parameterized tests to cover boundary
permutations.
---
Nitpick comments:
In
`@src/main/java/com/gpt/geumpumtabackend/maintenance/service/MaintenanceService.java`:
- Around line 21-25: The code currently constructs a new Maintenance with
request values inside maintenanceRepository.findById(...).orElseGet(() ->
Maintenance.initialize(request.status(), request.message())) and then
immediately calls maintenance.update(request.status(), request.message()),
causing duplicate assignment on creation; change the orElseGet to create a
default/empty Maintenance (e.g. use Maintenance.initialize() or another no-arg
initializer) so that you always obtain a maintenance instance and then call
maintenance.update(request.status(), request.message()) exactly once; reference
the Maintenance.initialize(...) call and the maintenance.update(...) invocation
to locate and modify the creation path.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
src/main/java/com/gpt/geumpumtabackend/global/config/security/SecurityConfig.javasrc/main/java/com/gpt/geumpumtabackend/global/exception/ExceptionType.javasrc/main/java/com/gpt/geumpumtabackend/global/maintenance/MaintenanceFilter.javasrc/main/java/com/gpt/geumpumtabackend/maintenance/api/MaintenanceApi.javasrc/main/java/com/gpt/geumpumtabackend/maintenance/controller/MaintenanceController.javasrc/main/java/com/gpt/geumpumtabackend/maintenance/domain/Maintenance.javasrc/main/java/com/gpt/geumpumtabackend/maintenance/domain/ServiceStatus.javasrc/main/java/com/gpt/geumpumtabackend/maintenance/dto/request/MaintenanceStatusUpdateRequest.javasrc/main/java/com/gpt/geumpumtabackend/maintenance/dto/response/MaintenanceStatusResponse.javasrc/main/java/com/gpt/geumpumtabackend/maintenance/repository/MaintenanceRepository.javasrc/main/java/com/gpt/geumpumtabackend/maintenance/service/MaintenanceService.javasrc/test/java/com/gpt/geumpumtabackend/unit/global/maintenance/MaintenanceFilterTest.javasrc/test/java/com/gpt/geumpumtabackend/unit/maintenance/service/MaintenanceServiceTest.java
🚀 1. 개요
📝 2. 주요 변경 사항
maintenance테이블을 통해 관리합니다.MaintenanceFilter를 통해 서버 점검 상태를 확인하고, 점검 중이라면 화이트리스트에 존재하지 않는 API의 호출이 차단됩니다.MaintenanceFilter는JwtAuthenticationFilter앞단에 위치하여 점검 상태에서는 JWT 인증 및 하위 로직까지 내려가지 않고 즉시 503을 반환합니다.📸 3. 스크린샷 (API 테스트 결과)
Summary by CodeRabbit
릴리스 노트
새로운 기능
테스트