Skip to content

Conversation

@hardwoong
Copy link
Member

관련 이슈

closed #12

작업한 내용

1. 커스텀 어노테이션 구현 및 적용

  • @CheckPage 어노테이션: 페이지 번호가 1 이상인지 검증
    • CheckPageValidator: 0 이하의 값에 대해 검증 실패 처리
    • GlobalExceptionHandlerConstraintViolationException 핸들러로 에러 처리
  • 모든 목록 조회 API의 page 파라미터에 적용

2. 구현된 API 목록 (4개)

2.1 내가 작성한 리뷰 목록 조회
  • 엔드포인트: GET /api/v1/reviews/my
  • 파라미터:
    • userId (required): 사용자 ID
    • page (default: 1): 페이지 번호 (1 이상)
  • 응답: 페이징 정보 포함 리뷰 목록
    • reviewList: 리뷰 목록
    • listSize: 현재 페이지 항목 수
    • currentPage: 현재 페이지 번호
    • totalPages: 전체 페이지 수
    • totalElements: 전체 항목 수
    • isFirst: 첫 페이지 여부
    • isLast: 마지막 페이지 여부
2.2 특정 가게의 미션 목록 조회
  • 엔드포인트: GET /api/v1/missions/stores/{storeId}
  • 파라미터:
    • storeId (path): 가게 ID
    • page (default: 1): 페이지 번호 (1 이상)
  • 응답: 페이징 정보 포함 미션 목록
2.3 내가 진행중인 미션 목록 조회
  • 엔드포인트: GET /api/v1/missions/my-ongoing
  • 파라미터:
    • userId (required): 사용자 ID
    • page (default: 1): 페이지 번호 (1 이상)
  • 응답: 페이징 정보 포함 진행중인 미션 목록
2.4 진행중인 미션 완료 처리
  • 엔드포인트: PATCH /api/v1/missions/complete
  • 요청: { "challengeMissionId": Long }
  • 동작:
    1. 진행중인 미션 상태를 IN_PROGRESSCOMPLETED로 변경
    2. completedAt 필드에 현재 시간 설정
    3. 변경된 미션 정보 조회하여 반환
  • 응답: 완료 처리된 미션 정보
    • challengeMissionId: 도전 미션 ID
    • status: 미션 상태 (COMPLETED)
    • completedAt: 완료 시간
    • updatedAt: 수정 시간

3. 추가 구현 사항

  • UserMission.updateStatus(): 미션 상태 변경 메서드 추가
  • MissionErrorCode.MISSION_ALREADY_COMPLETED: 이미 완료된 미션 에러 코드 추가
  • MissionSuccessCode.MISSION_COMPLETED: 미션 완료 성공 코드 추가

PR Point 및 참고사항

요구사항

  • 오프셋 페이징 처리 (한 페이지에 10개씩 조회)
  • 프론트엔드는 1 이상의 page 번호 전달 (0 또는 음수 고려 X)
  • @CheckPage 커스텀 어노테이션 구현 및 적용
  • RestControllerAdvice와 연계하여 에러 처리
  • 모든 API에 Swagger 명세 작성
  • Converter에서 Stream 사용 (for문 사용 안 함)
  • 빌더 패턴 사용

참고사항

  • 페이지 번호는 1부터 시작하며, 기본값은 1
  • 한 페이지당 10개의 항목이 조회됨

@hardwoong hardwoong self-assigned this Nov 23, 2025
@hardwoong hardwoong added the enhancement New feature or request label Nov 23, 2025
@hardwoong hardwoong linked an issue Nov 23, 2025 that may be closed by this pull request
Copy link

@ggamnunq ggamnunq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good

boolean existsById(Long missionId);

Page<Mission> getStoreMissions(Long storeId, Integer page);
Page<UserMission> getMyOngoingMissions(Long userId, Integer page);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

진행중인 미션을 조회하는 메서드를 만드는 것보단, Status를 메서드의 파라미터로 포함해주면 이후 재사용 가능한 메서드가 됩니다.

return ReviewResDTO.ReviewPreViewListDTO.builder()
.reviewList(reviewList)
.listSize(reviewList.size())
.currentPage(reviewPage.getNumber() + 1) // 0-based를 1-based로 변환

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1-based로 변경하는건 converter로 변경할 때가 아니고 별도로 구조나 로직을 구성해서 만드는게 깔끔합니다.

.totalPages(reviewPage.getTotalPages())
.totalElements(reviewPage.getTotalElements())
.isFirst(reviewPage.isFirst())
.isLast(reviewPage.isLast())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

페이징 정보는 페이징 전용 클래스를 만들어 그걸 공통 응답값으로 사용하면 좋습니다.

@Query("SELECT r FROM Review r " +
"WHERE r.user.userId = :userId " +
"ORDER BY r.reviewId DESC")
Page<Review> findByUserUserId(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pageable에 정렬 정보도 넣어줄 수 있어요.
query문으로 정렬해도 되지만, 그러려면 메서드명에 desc 정렬을 헸다는걸 표현해야 할듯합니다.

@hardwoong hardwoong merged commit 8c201e6 into develop Dec 15, 2025
@hardwoong hardwoong deleted the Feat/chapter9 branch December 15, 2025 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Week9 Mission

3 participants