🐛 버그 설명
#457 에서 리뷰 목록 조회 3종의 500 에러를 수정하면서 PageRequest.of(pageable.getPageNumber() - 1, ...) 보정을 제거했습니다. 500은 해소됐지만, 그 결과 해당 API들만 0-based 페이징으로 바뀌어 프론트와의 기존 계약이 깨졌습니다.
현상
GET /reviews/student, GET /reviews/partner, GET /reviews/store/{storeId} 세 API에서 page=1을 보내면 첫 페이지가 아니라 두 번째 페이지가 반환됩니다.
#457의 판단 오류
이슈 본문에 *"spring.data.web.pageable.one-indexed-parameters 설정도 없어 이 -1 보정을 정당화할 근거가 없다"*고 적었으나, 이 저장소는 설정이 아니라 코드로 1-based 규약을 구현하고 있었습니다.
| 근거 |
위치 |
@CheckPage 기본 메시지 "페이지가 1보다 작을 수 없습니다" |
global/exception/annotation/CheckPage.java |
CheckPageValidator가 value > 0 검증 후 PAGE_UNDER_ONE 반환 |
global/exception/validator/CheckPageValidator.java |
PageRequest.of(page - 1, size, ...) |
InquiryServiceImpl, BackofficeInquiryServiceImpl, NotificationQueryServiceImpl, BackofficeNotificationServiceImpl |
Math.max(pageable.getPageNumber() - 1, 0) + "프론트에서 1-based 페이지를 보낸 경우 0-based 로 보정" 주석 |
StudentServiceImpl#getUnreviewedUsage |
마지막 항목이 이번 문제의 정답 패턴이며, 이미 같은 저장소에 존재했습니다. 보정을 제거하는 대신 이 패턴을 적용했어야 합니다.
현재 상태
리뷰 3개 API만 0-based, 문의·알림·백오피스·학생 API는 1-based로 규약이 엇갈려 있습니다.
✅ 수정 목록
📝 참고 사항
기대 동작
| 요청 |
결과 |
?page=1 |
첫 페이지 — 기존 프론트 계약 유지 |
page 생략 |
첫 페이지 — #457이 고치려던 500 해소 |
?page=0 |
첫 페이지 — 관용 처리 |
500 수정 목적을 유지하면서 계약도 깨지 않습니다. 프론트 앱 수정은 필요하지 않습니다.
별건
@CheckPage는 정의와 validator만 있고 실제 사용처가 0건입니다. 1-based 규약을 코드로 강제하려면 페이징 컨트롤러에 부착해야 하고, 그럴 계획이 없다면 제거 대상입니다. 이 이슈 범위 밖이라 별도로 논의가 필요합니다.
관련
🐛 버그 설명
#457 에서 리뷰 목록 조회 3종의 500 에러를 수정하면서
PageRequest.of(pageable.getPageNumber() - 1, ...)보정을 제거했습니다. 500은 해소됐지만, 그 결과 해당 API들만 0-based 페이징으로 바뀌어 프론트와의 기존 계약이 깨졌습니다.현상
GET /reviews/student,GET /reviews/partner,GET /reviews/store/{storeId}세 API에서page=1을 보내면 첫 페이지가 아니라 두 번째 페이지가 반환됩니다.#457의 판단 오류
이슈 본문에 *"
spring.data.web.pageable.one-indexed-parameters설정도 없어 이-1보정을 정당화할 근거가 없다"*고 적었으나, 이 저장소는 설정이 아니라 코드로 1-based 규약을 구현하고 있었습니다.@CheckPage기본 메시지 "페이지가 1보다 작을 수 없습니다"global/exception/annotation/CheckPage.javaCheckPageValidator가value > 0검증 후PAGE_UNDER_ONE반환global/exception/validator/CheckPageValidator.javaPageRequest.of(page - 1, size, ...)InquiryServiceImpl,BackofficeInquiryServiceImpl,NotificationQueryServiceImpl,BackofficeNotificationServiceImplMath.max(pageable.getPageNumber() - 1, 0)+ "프론트에서 1-based 페이지를 보낸 경우 0-based 로 보정" 주석StudentServiceImpl#getUnreviewedUsage마지막 항목이 이번 문제의 정답 패턴이며, 이미 같은 저장소에 존재했습니다. 보정을 제거하는 대신 이 패턴을 적용했어야 합니다.
현재 상태
리뷰 3개 API만 0-based, 문의·알림·백오피스·학생 API는 1-based로 규약이 엇갈려 있습니다.
✅ 수정 목록
ReviewServiceImpl의checkStudentReview/checkPartnerReview/checkStoreReview에Math.max(pageable.getPageNumber() - 1, 0)보정 적용page=1/page생략 /page=0)가 모두 첫 페이지를 반환하는지 테스트 추가📝 참고 사항
기대 동작
?page=1page생략?page=0500 수정 목적을 유지하면서 계약도 깨지 않습니다. 프론트 앱 수정은 필요하지 않습니다.
별건
@CheckPage는 정의와 validator만 있고 실제 사용처가 0건입니다. 1-based 규약을 코드로 강제하려면 페이징 컨트롤러에 부착해야 하고, 그럴 계획이 없다면 제거 대상입니다. 이 이슈 범위 밖이라 별도로 논의가 필요합니다.관련