Skip to content

Conversation

@Yujin1219
Copy link
Member

@Yujin1219 Yujin1219 commented Nov 25, 2025

#️⃣ 연관된 이슈

📝 미션 번호

10주차 Misson

📋 구현 사항

  • SecurityConfig 작성
  • JwtAuthenticationFilter 작성
  • JwtProvider 작성

📌 PR 포인트

  • 나머지는 저번에 미리 했었던거였어염

✅ 체크리스트

  • Reviewer에 파트장을 선택 했나요?
  • Assignees에 본인을 선택 했나요?
  • Merge 하려는 브랜치가 올바르게 설정되어 있나요?
  • 컨벤션을 지키고 있나요?
  • 로컬에서 실행했을 때 에러가 발생하지 않나요?
  • 불필요한 주석이 제거되었나요?
  • 코드 스타일이 일관적인가요?

🤔 질문 & 고민

@Yujin1219 Yujin1219 self-assigned this Nov 25, 2025
@Yujin1219 Yujin1219 added the ✨ Feature 기능 개발 label Nov 25, 2025
@Yujin1219 Yujin1219 linked an issue Nov 25, 2025 that may be closed by this pull request
5 tasks
@Yujin1219 Yujin1219 merged commit 83d15e3 into main Nov 25, 2025
1 check passed
@Yujin1219 Yujin1219 deleted the Week9 branch November 25, 2025 06:40
@coderabbitai
Copy link

coderabbitai bot commented Nov 25, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link

coderabbitai bot commented Nov 25, 2025

워크스루

미션 및 리뷰 도메인에 대한 DTO 이름 변경(MyMissionDTO → MissionDTO), 커서 기반 페이지네이션 추가, 미션 완료 기능 구현, 스토어별 미션/리뷰 조회 엔드포인트 추가, 관련 에러 상태 코드 신규 정의가 이루어졌습니다.

변경 사항

응집 / 파일(들) 변경 요약
미션 DTO 리팩토링
src/main/java/com/example/umc9th/domain/mission/dto/MissionResponse.java, src/main/java/com/example/umc9th/domain/mission/converter/MissionConverter.java, src/main/java/com/example/umc9th/domain/mission/service/MissionService*.java
MyMissionDTO를 MissionDTO로, MyMissionListDTO를 MissionListDTO로 이름 변경. MissionDTO에 missionStatus 필드 추가. 이에 따른 모든 참조 위치 업데이트 및 컨버터 로직 조정. 신규 toMissionDTO(Mission) 메서드 추가.
미션 완료 기능
src/main/java/com/example/umc9th/domain/mission/controller/MissionController.java, src/main/java/com/example/umc9th/domain/mission/entity/MissionByMember.java
PATCH /api/missions/{mbmId}/complete 엔드포인트 추가. MissionByMember에 updateStatus(MissionStatus) 메서드 신규 추가. 상태 변경 시 IN_PROGRESS 검증 로직 포함.
미션 커서 기반 페이지네이션
src/main/java/com/example/umc9th/domain/mission/repository/MissionRepository.java, src/main/java/com/example/umc9th/domain/mission/service/MissionService*.java
findMissionsByStore(Long, Long, Pageable) 메서드 추가로 스토어별 미션 조회 지원. getMissionListByStore(Long, Long) 비즈니스 로직 구현. nextCursorId 계산 로직 포함.
리뷰 커서 기반 페이지네이션
src/main/java/com/example/umc9th/domain/review/repository/ReviewRepository.java, src/main/java/com/example/umc9th/domain/review/service/ReviewService*.java
findReviewsByStore(Long, Long, Pageable) 메서드 추가. getReviewList(Long, Long) 구현으로 스토어별 리뷰 조회 및 이미지 배치 로딩 처리.
API 엔드포인트 추가
src/main/java/com/example/umc9th/domain/store/controller/StoreController.java
GET /api/stores/{storeId}/reviews 및 GET /api/stores/{storeId}/missions 엔드포인트 추가. ReviewService, MissionService 의존성 주입 및 Swagger 주석 처리.
에러 상태 코드
src/main/java/com/example/umc9th/global/apiPayload/code/status/ErrorStatus.java
MISSION_BY_MEMBER_NOT_FOUND, MISSION_STATUS_NOT_IN_PROGRESS 신규 에러 상수 추가. STORE_NOT_FOUND를 세미콜론에서 쉼표로 변경.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.85% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 9주차 API 및 페이징 기능 구현이라는 주요 변경 사항을 요약하고 있으나, 구체적인 세부 내용(리뷰 목록, 미션 목록, 미션 완료 API)이 누락되어 있습니다.
Description check ✅ Passed PR 설명은 템플릿의 필수 섹션(연관된 이슈, 미션 번호, 구현 사항, PR 포인트)을 포함하고 있으며, 구현된 API 3가지를 명확히 나열하고 있습니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch Week9

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Comment @coderabbitai help to get the list of available commands and usage tips.

@Yujin1219
Copy link
Member Author

✅ Actions performed

@coderabbitai review

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (6)
src/main/java/com/example/umc9th/domain/review/service/ReviewService.java (1)

5-6: 사용되지 않는 import 존재

PageableSlice는 이 인터페이스에서 직접 사용되지 않습니다. 구현체(ReviewServiceImpl)에서만 필요한 import입니다.

 package com.example.umc9th.domain.review.service;
 
 import com.example.umc9th.domain.review.dto.ReviewRequest;
 import com.example.umc9th.domain.review.dto.ReviewResponse;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Slice;
src/main/java/com/example/umc9th/domain/mission/entity/MissionByMember.java (1)

37-41: 상태 전이 유효성 검증 추가 고려

현재 구현은 어떤 상태에서든 다른 상태로 변경이 가능합니다. 비즈니스 로직상 COMPLETEDIN_PROGRESS와 같은 역방향 전이가 허용되어서는 안 될 수 있습니다.

상태 전이 검증을 추가하는 것을 권장합니다:

     // 미션 상태 변경 메소드
     public void updateStatus(MissionStatus status) {
+        if (this.status == MissionStatus.COMPLETED) {
+            throw new IllegalStateException("이미 완료된 미션의 상태는 변경할 수 없습니다.");
+        }
         this.status = status;
     }

또는 명시적인 메서드로 분리하는 방법도 있습니다:

public void complete() {
    if (this.status != MissionStatus.IN_PROGRESS) {
        throw new IllegalStateException("진행 중인 미션만 완료할 수 있습니다.");
    }
    this.status = MissionStatus.COMPLETED;
}
src/main/java/com/example/umc9th/domain/review/service/ReviewServiceImpl.java (1)

62-94: 코드 중복 개선 고려

getMyReviewsgetReviewList 메서드에서 이미지 조회, DTO 변환, nextCursorId 계산 로직이 중복됩니다. 공통 로직을 private 헬퍼 메서드로 추출하면 유지보수성이 향상됩니다.

private ReviewResponse.ReviewListDTO buildReviewListDTO(Slice<Review> reviewSlice) {
    List<Long> reviewIds = reviewSlice.getContent().stream()
            .map(Review::getId)
            .toList();

    Map<Long, List<String>> reviewImageMap = reviewRepositoryCustom.findReviewImages(reviewIds);

    List<ReviewResponse.ReviewResultDTO> dtoList =
            ReviewConverter.toReviewResultDTOList(reviewSlice.getContent(), reviewImageMap);

    Long nextCursorId = (reviewSlice.hasNext() && !dtoList.isEmpty())
            ? dtoList.get(dtoList.size() - 1).getReviewId()
            : null;

    return ReviewResponse.ReviewListDTO.builder()
            .reviewList(dtoList)
            .hasNext(reviewSlice.hasNext())
            .nextCursorId(nextCursorId)
            .build();
}

Also applies to: 96-125

src/main/java/com/example/umc9th/domain/store/controller/StoreController.java (1)

9-9: 사용되지 않는 import 제거

Review 엔티티가 import 되어 있지만 이 컨트롤러에서 사용되지 않습니다.

-import com.example.umc9th.domain.review.entity.Review;
src/main/java/com/example/umc9th/domain/mission/service/MissionService.java (1)

4-4: 사용되지 않는 import 제거

Mission 엔티티가 import 되어 있지만 이 인터페이스에서 사용되지 않습니다.

-import com.example.umc9th.domain.mission.entity.Mission;
src/main/java/com/example/umc9th/domain/mission/converter/MissionConverter.java (1)

28-55: 커서 기반 페이지네이션이 올바르게 구현되었습니다.

DTO 타입 변경 및 커서 기반 페이지네이션 로직이 정확합니다. 빈 리스트 처리와 마지막 미션의 deadline과 ID를 다음 커서로 설정하는 로직이 적절합니다.

다만, 30번 라인의 주석을 업데이트하면 코드 일관성이 향상됩니다:

-        // 각 MissionByMember 엔터티 -> MyMissionDTO로 변환 -> list로
+        // 각 MissionByMember 엔터티 -> MissionDTO로 변환 -> list로
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f382de and 7f68030.

📒 Files selected for processing (12)
  • src/main/java/com/example/umc9th/domain/mission/controller/MissionController.java (2 hunks)
  • src/main/java/com/example/umc9th/domain/mission/converter/MissionConverter.java (3 hunks)
  • src/main/java/com/example/umc9th/domain/mission/dto/MissionResponse.java (1 hunks)
  • src/main/java/com/example/umc9th/domain/mission/entity/MissionByMember.java (1 hunks)
  • src/main/java/com/example/umc9th/domain/mission/repository/MissionRepository.java (1 hunks)
  • src/main/java/com/example/umc9th/domain/mission/service/MissionService.java (1 hunks)
  • src/main/java/com/example/umc9th/domain/mission/service/MissionServiceImpl.java (2 hunks)
  • src/main/java/com/example/umc9th/domain/review/repository/ReviewRepository.java (2 hunks)
  • src/main/java/com/example/umc9th/domain/review/service/ReviewService.java (1 hunks)
  • src/main/java/com/example/umc9th/domain/review/service/ReviewServiceImpl.java (3 hunks)
  • src/main/java/com/example/umc9th/domain/store/controller/StoreController.java (3 hunks)
  • src/main/java/com/example/umc9th/global/apiPayload/code/status/ErrorStatus.java (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
src/main/java/com/example/umc9th/domain/store/controller/StoreController.java (2)
src/main/java/com/example/umc9th/domain/review/dto/ReviewResponse.java (1)
  • ReviewResponse (11-37)
src/main/java/com/example/umc9th/domain/store/dto/StoreResponse.java (1)
  • StoreResponse (11-36)
src/main/java/com/example/umc9th/domain/review/service/ReviewServiceImpl.java (2)
src/main/java/com/example/umc9th/domain/review/converter/ReviewConverter.java (1)
  • ReviewConverter (13-50)
src/main/java/com/example/umc9th/domain/review/dto/ReviewResponse.java (1)
  • ReviewResponse (11-37)
src/main/java/com/example/umc9th/domain/mission/dto/MissionResponse.java (2)
src/main/java/com/example/umc9th/domain/member/dto/MemberResponse.java (1)
  • Builder (11-22)
src/main/java/com/example/umc9th/domain/mission/dto/MissionRequest.java (1)
  • Getter (12-23)
src/main/java/com/example/umc9th/domain/mission/service/MissionServiceImpl.java (4)
src/main/java/com/example/umc9th/global/apiPayload/exception/handler/ErrorHandler.java (1)
  • ErrorHandler (6-10)
src/main/java/com/example/umc9th/domain/store/service/StoreServiceImpl.java (1)
  • Service (20-51)
src/main/java/com/example/umc9th/domain/mission/converter/MissionConverter.java (1)
  • MissionConverter (14-85)
src/main/java/com/example/umc9th/domain/mission/dto/MissionResponse.java (1)
  • MissionResponse (12-47)
src/main/java/com/example/umc9th/domain/mission/converter/MissionConverter.java (1)
src/main/java/com/example/umc9th/domain/mission/dto/MissionResponse.java (1)
  • MissionResponse (12-47)
🔇 Additional comments (11)
src/main/java/com/example/umc9th/domain/review/service/ReviewService.java (1)

18-19: LGTM!

새로운 getReviewList 메서드 시그니처가 기존 getMyReviews 패턴과 일관성 있게 잘 추가되었습니다. 커서 기반 페이지네이션을 위한 적절한 파라미터 구성입니다.

src/main/java/com/example/umc9th/domain/mission/repository/MissionRepository.java (1)

31-47: LGTM!

커서 기반 페이지네이션 쿼리가 기존 findAvailableMissionsByRegion 패턴과 일관성 있게 잘 구현되었습니다. JPQL 문법과 커서 조건 (:cursorId IS NULL OR m.id < :cursorId)이 내림차순 정렬에 적합하게 작성되었습니다.

src/main/java/com/example/umc9th/domain/review/repository/ReviewRepository.java (1)

33-49: LGTM!

MissionRepository.findMissionsByStore와 동일한 패턴으로 커서 기반 페이지네이션이 잘 구현되었습니다. 문서화도 명확합니다.

src/main/java/com/example/umc9th/domain/store/controller/StoreController.java (2)

67-79: LGTM!

커서 기반 페이지네이션을 사용한 리뷰 목록 조회 API가 기존 패턴과 일관되게 구현되었습니다. Swagger 어노테이션도 적절하게 작성되었습니다.


81-93: LGTM!

미션 목록 조회 API 구현이 적절합니다. 리뷰 목록 조회 API와 일관된 패턴을 따르고 있습니다.

src/main/java/com/example/umc9th/domain/mission/controller/MissionController.java (1)

34-44: LGTM!

미션 완료 처리 API가 적절하게 구현되었습니다. PATCH 메서드 사용과 Swagger 문서화가 올바릅니다.

src/main/java/com/example/umc9th/global/apiPayload/code/status/ErrorStatus.java (1)

25-28: LGTM!

새로운 미션 관련 에러 코드가 적절하게 추가되었습니다. HttpStatus.CONFLICT는 상태 충돌 상황에 적합합니다.

포맷팅 관련 마이너 제안: 27번 줄과 28번 줄 사이에 빈 줄을 추가하면 가독성이 향상됩니다.

-    MISSION_STATUS_NOT_IN_PROGRESS(HttpStatus.CONFLICT, "MISSION4091","해당 미션은 현재 진행 중(IN_PROGRESS) 상태가 아니므로 완료할 수 없습니다.");
+    MISSION_STATUS_NOT_IN_PROGRESS(HttpStatus.CONFLICT, "MISSION4091","해당 미션은 현재 진행 중(IN_PROGRESS) 상태가 아니므로 완료할 수 없습니다.");
+
     private final HttpStatus httpStatus;
src/main/java/com/example/umc9th/domain/mission/service/MissionService.java (1)

12-18: LGTM!

인터페이스 메서드 시그니처가 명확하게 정의되었습니다. 주석을 통한 메서드 설명도 적절합니다.

src/main/java/com/example/umc9th/domain/mission/service/MissionServiceImpl.java (2)

47-78: LGTM!

가게 미션 목록 조회 로직이 커서 기반 페이지네이션 패턴을 잘 따르고 있습니다. hasNext 조건과 커서 계산 로직이 적절합니다.


80-100: 미션 완료 처리 로직 구현 적절

트랜잭션 처리, 상태 검증, 에러 핸들링이 잘 구현되어 있습니다. ErrorStatus.MISSION_BY_MEMBER_NOT_FOUNDMISSION_STATUS_NOT_IN_PROGRESS 에러 코드가 적절하게 사용되었습니다.

src/main/java/com/example/umc9th/domain/mission/converter/MissionConverter.java (1)

16-26: LGTM! DTO 타입 변경 및 missionStatus 필드 추가가 올바르게 적용되었습니다.

MyMissionDTO에서 MissionDTO로의 타입 변경이 정확하며, .missionStatus(missionByMember.getStatus()) 필드 매핑이 올바르게 추가되어 DTO 정의와 일치합니다.

@RequestParam(defaultValue = "10") int size
) {
MissionResponse.MyMissionListDTO response = missionService.getMyMissions(1L, status, cursorDeadline, cursorId, size);
MissionResponse.MissionListDTO response = missionService.getMyMissions(1L, status, cursorDeadline, cursorId, size);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

하드코딩된 memberId 수정 필요

memberId1L로 하드코딩되어 있습니다. 실제 환경에서는 인증된 사용자의 ID를 Security Context나 JWT 토큰에서 가져와야 합니다.

-        MissionResponse.MissionListDTO response = missionService.getMyMissions(1L, status, cursorDeadline, cursorId, size);
+        // TODO: 인증 구현 후 실제 사용자 ID로 변경 필요
+        Long memberId = /* SecurityContextHolder 또는 @AuthenticationPrincipal에서 추출 */;
+        MissionResponse.MissionListDTO response = missionService.getMyMissions(memberId, status, cursorDeadline, cursorId, size);

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
src/main/java/com/example/umc9th/domain/mission/controller/MissionController.java
around line 30, the memberId is hardcoded as 1L; replace that hardcoded value
with the authenticated user's ID retrieved from the security context or JWT
(e.g., extract the user ID from SecurityContextHolder or a
@AuthenticationPrincipal argument) and pass that ID to
missionService.getMyMissions; ensure you handle the case when authentication is
missing (throw an appropriate exception or return 401) and update method
signature if needed to accept the principal.

Comment on lines +76 to +84
public static MissionResponse.MissionDTO toMissionDTO(Mission mission) {
return MissionResponse.MissionDTO.builder()
.storeName(mission.getStore().getName())
.missionContent(mission.getContent())
.targetAmount(mission.getTargetAmount())
.rewardPoint(mission.getRewardPoint())
.deadline(mission.getDeadline())
.build();
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

missionStatus 필드 누락 여부를 확인해주세요.

새로운 toMissionDTO 메서드는 Mission 엔티티를 MissionDTO로 변환하지만, missionStatus 필드를 설정하지 않습니다. 반면 toMyMissionDTO (16-26번 라인)는 missionStatus를 포함합니다.

MissionResponse.MissionDTOmissionStatus 필드를 포함하므로, 이 필드가 설정되지 않으면 API 응답에서 null 값이 반환될 수 있습니다. 이것이 의도된 동작인지(예: 사용자 컨텍스트가 없는 가게별 미션 목록) 확인이 필요합니다.

다음 스크립트로 toMissionDTO 메서드의 사용 컨텍스트를 확인하여 누락된 missionStatus가 문제를 일으키는지 검증해주세요:


🏁 Script executed:

#!/bin/bash
# toMissionDTO 메서드 사용처를 찾아 컨텍스트 확인

# toMissionDTO 메서드 호출 위치 검색
rg -nP --type=java -C5 'MissionConverter\.toMissionDTO\s*\(' -g '!**/converter/**'

# MissionDTO를 반환하는 API 엔드포인트 확인
rg -nP --type=java -C5 'MissionDTO|MissionListDTO' -g '**/controller/**'

Length of output: 5199


실제 toMissionDTO() 호출 위치를 서비스 레이어에서 찾아야 합니다. 다음을 확인하겠습니다:

  • Service 레이어에서 toMissionDTO() 실제 호출 위치
  • MissionDTO 클래스 정의에서 missionStatus 필드가 필수인지 확인

🏁 Script executed:

#!/bin/bash
# 서비스 레이어에서 toMissionDTO 호출 위치 확인
rg -nP --type=java -C8 'toMissionDTO|toMyMissionDTO' -g '**/service/**'

# MissionDTO 클래스 정의 확인 (missionStatus 필드 타입 확인)
rg -nP --type=java -A30 'class MissionDTO' -g '**/response/**'

Length of output: 3550


MissionDTO 클래스 정의를 찾아야 합니다. 더 넓은 범위로 검색하겠습니다:


🏁 Script executed:

#!/bin/bash
# MissionResponse 클래스 찾기
fd -t f -e java 'MissionResponse.java'

# 찾은 파일에서 MissionDTO 클래스 정의 확인
fd -t f -e java 'MissionResponse.java' | xargs cat

Length of output: 1244


toMissionDTO 메서드에서 missionStatus 필드 누락 - 필수 수정

검증 결과 문제가 확인되었습니다:

  • MissionDTO 클래스의 missionStatus 필드는 MissionStatus 타입으로 선언되어 있으며, Nullable이 아닙니다.
  • toMissionDTO 메서드는 line 58 (MissionServiceImpl.getMissionListByStore)에서 호출되며, missionStatus 필드를 설정하지 않습니다.
  • 결과적으로 가게 미션 목록 조회 API 응답에서 missionStatusnull로 반환됩니다.

이는 API 응답 계약 위반입니다. MissionDTO는 두 가지 다른 문맥에서 사용됩니다:

  • getMissionListByStore: 사용자 컨텍스트 없음 (null missionStatus)
  • getMyMissions: 사용자 컨텍스트 있음 (populated missionStatus)

해결 방안:

  1. MissionDTO.missionStatus@Nullable 또는 Optional<MissionStatus>로 변경하거나
  2. 다른 DTO 타입을 사용하여 두 문맥을 분리하거나
  3. toMissionDTO에서 기본값을 설정하여 missionStatus를 populate하세요.
🤖 Prompt for AI Agents
In
src/main/java/com/example/umc9th/domain/mission/converter/MissionConverter.java
around lines 76 to 84, the toMissionDTO method currently omits the non-nullable
missionStatus field causing nulls in API responses; update the method to set
missionStatus (e.g., .missionStatus(mission.getMissionStatus())) so the DTO is
always populated, or if missionStatus should be context-dependent, create a
second DTO or an overloaded converter that accepts a nullable/derived status and
use that from getMissionListByStore; ensure the chosen fix preserves the
non-null contract of MissionResponse.MissionDTO.

Comment on lines +17 to 26
@Schema(description = "미션 목록의 개별 미션 응답")
public static class MissionDTO {

private String storeName;
private String missionContent;
private Integer rewardPoint;
private Integer targetAmount;
private LocalDate deadline;
private MissionStatus missionStatus;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

MissionConverter.toMissionDTO에서 missionStatus가 설정되지 않음

MissionDTOmissionStatus 필드가 추가되었지만, MissionConverter.toMissionDTO(Mission mission) 메서드에서는 이 필드를 설정하지 않습니다 (관련 코드 스니펫 lines 72-80 참조). 이로 인해 가게 미션 목록 조회 시 missionStatus가 항상 null로 반환됩니다.

MissionConverter.toMissionDTO 메서드에서 missionStatus를 설정하거나, 가게 미션 목록 전용 DTO를 별도로 분리하는 것을 고려하세요.


🏁 Script executed:

#!/bin/bash
# MissionConverter.toMissionDTO 메서드에서 missionStatus 설정 여부 확인
ast-grep --pattern $'public static MissionResponse.MissionDTO toMissionDTO(Mission mission) {
  $$$
}'

Length of output: 1179



---

🏁 Script executed:

```shell
#!/bin/bash
# 다른 converter 메서드들에서 missionStatus 설정 여부 확인
ast-grep --pattern $'public static MissionResponse.MyMissionDTO toMyMissionDTO($_) {
  $$$
}'

Length of output: 0


🏁 Script executed:

#!/bin/bash
# toMissionDTO 호출 위치 확인
rg -n 'toMissionDTO' --type=java

Length of output: 295


🏁 Script executed:

#!/bin/bash
# MissionDTO 필드 정의 및 주석 확인
rg -n -A10 'class MissionDTO' --type=java src/main/java/com/example/umc9th/domain/mission/dto/

Length of output: 1121



---

🏁 Script executed:

```shell
#!/bin/bash
# MissionServiceImpl 라인 58 근처 컨텍스트 확인 (어느 메서드인지 확인)
rg -n -B15 -A5 '\.map\(MissionConverter::toMissionDTO\)' --type=java src/main/java/com/example/umc9th/domain/mission/service/

Length of output: 2476


🏁 Script executed:

#!/bin/bash
# MissionDTO의 missionStatus 필드 주석 및 어노테이션 확인
rg -n -B3 'private MissionStatus missionStatus' --type=java

Length of output: 459


🏁 Script executed:

#!/bin/bash
# MissionStatus 필드가 설정되는 다른 메서드 확인
rg -n 'missionStatus' --type=java src/main/java/com/example/umc9th/domain/mission/

Length of output: 263



---

🏁 Script executed:

```shell
#!/bin/bash
# MissionConverter.java 라인 24 주변 컨텍스트 확인 (어느 메서드인지)
rg -n -B10 -A2 '\.missionStatus\(missionByMember\.getStatus\(\)\)' --type=java src/main/java/com/example/umc9th/domain/mission/converter/

Length of output: 1678


MissionConverter.toMissionDTO 메서드에서 missionStatus 필드가 설정되지 않음

toMissionDTO(Mission mission) 메서드(src/main/java/com/example/umc9th/domain/mission/converter/MissionConverter.java, 76-83줄)는 MissionDTO를 빌드할 때 missionStatus 필드를 설정하지 않습니다. 반면 toMyMissionDTO(MissionByMember missionByMember) 메서드는 동일한 MissionDTO 클래스에 missionStatus를 설정합니다(24줄). 이로 인해 getMissionListByStore 엔드포인트에서 반환되는 미션 목록의 missionStatus가 항상 null이 됩니다.

두 메서드가 동일한 DTO를 공유하므로, toMissionDTO 메서드에서도 missionStatus를 설정하거나, 가게 미션 목록 전용 DTO를 별도로 분리하는 것을 권장합니다.

🤖 Prompt for AI Agents
In src/main/java/com/example/umc9th/domain/mission/dto/MissionResponse.java
around lines 17-26 and in
src/main/java/com/example/umc9th/domain/mission/converter/MissionConverter.java
(toMissionDTO method, ~lines 76-83), the MissionDTO.missionStatus is not being
set, causing null values in getMissionListByStore responses; update the
toMissionDTO(Mission mission) implementation to populate missionStatus from the
Mission entity (e.g., mission.getMissionStatus()) when building MissionDTO, or
if you prefer separate representations, introduce a store-specific DTO and map
missionStatus there—make the change so both converter methods produce the same
missionStatus value.

Comment on lines +94 to +96
// 3. 상태 변경 (COMPLETE)
// MissionByMember 엔티티에 updateStatus(MissionStatus status) 메서드가 존재한다고 가정
mbm.updateStatus(MissionStatus.SUCCESS);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

주석과 코드 불일치

주석에는 "COMPLETE"로 상태를 변경한다고 되어 있지만, 실제 코드는 MissionStatus.SUCCESS를 사용합니다. 주석을 코드와 일치하도록 수정하거나, 의도한 상태 값이 무엇인지 확인이 필요합니다.

-        // 3. 상태 변경 (COMPLETE)
+        // 3. 상태 변경 (SUCCESS)
         // MissionByMember 엔티티에 updateStatus(MissionStatus status) 메서드가 존재한다고 가정
         mbm.updateStatus(MissionStatus.SUCCESS);

🏁 Script executed:

#!/bin/bash
# MissionStatus enum에 정의된 상태 값 확인
ast-grep --pattern $'public enum MissionStatus {
  $$$
}'

Length of output: 308


주석 수정 필요

MissionStatus 열거형에 "COMPLETE" 상태는 존재하지 않습니다. 정의된 상태는 IN_PROGRESS, SUCCESS, FAILED입니다. 코드의 MissionStatus.SUCCESS 사용은 올바르므로, 주석을 수정하여 일치시켜야 합니다.

-        // 3. 상태 변경 (COMPLETE)
+        // 3. 상태 변경 (SUCCESS)
         // MissionByMember 엔티티에 updateStatus(MissionStatus status) 메서드가 존재한다고 가정
         mbm.updateStatus(MissionStatus.SUCCESS);
🤖 Prompt for AI Agents
In
src/main/java/com/example/umc9th/domain/mission/service/MissionServiceImpl.java
around lines 94 to 96, the inline comment incorrectly mentions a "COMPLETE"
status that doesn't exist in MissionStatus; update the comment to reflect the
actual enum values (e.g., mention SUCCESS) so it matches the code that calls
mbm.updateStatus(MissionStatus.SUCCESS); keep the comment concise and accurate
to avoid confusion.

Comment on lines +96 to +97
// 가게별 리뷰 조회
public ReviewResponse.ReviewListDTO getReviewList(Long storeId, Long cursorId) {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

@Override 어노테이션 누락

getReviewList 메서드는 ReviewService 인터페이스를 구현하므로 @Override 어노테이션을 추가해야 합니다.

     // 가게별 리뷰 조회
+    @Override
     public ReviewResponse.ReviewListDTO getReviewList(Long storeId, Long cursorId) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 가게별 리뷰 조회
public ReviewResponse.ReviewListDTO getReviewList(Long storeId, Long cursorId) {
// 가게별 리뷰 조회
@Override
public ReviewResponse.ReviewListDTO getReviewList(Long storeId, Long cursorId) {
🤖 Prompt for AI Agents
In src/main/java/com/example/umc9th/domain/review/service/ReviewServiceImpl.java
around lines 96 to 97, the getReviewList method implements the ReviewService
interface but is missing the @Override annotation; add @Override directly above
the method declaration public ReviewResponse.ReviewListDTO getReviewList(Long
storeId, Long cursorId) to clearly indicate it is overriding the interface
method (no imports needed).

Comment on lines +96 to +101
// 가게별 리뷰 조회
public ReviewResponse.ReviewListDTO getReviewList(Long storeId, Long cursorId) {

Pageable pageable = PageRequest.of(0, PAGE_SIZE);

Slice<Review> reviewSlice = reviewRepository.findReviewsByStore(storeId, cursorId, pageable);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

가게 존재 여부 검증 누락

createReview 메서드(Line 49-50)에서는 storeId로 가게 존재 여부를 검증하지만, getReviewList에서는 검증 없이 바로 쿼리를 실행합니다. 존재하지 않는 storeId로 요청 시 빈 결과가 반환되어 사용자가 "리뷰가 없음"과 "가게가 없음"을 구분할 수 없습니다.

     // 가게별 리뷰 조회
+    @Override
     public ReviewResponse.ReviewListDTO getReviewList(Long storeId, Long cursorId) {
 
+        // 가게 존재 여부 검증
+        storeRepository.findById(storeId)
+                .orElseThrow(() -> new ErrorHandler(ErrorStatus.STORE_NOT_FOUND));
+
         Pageable pageable = PageRequest.of(0, PAGE_SIZE);
🤖 Prompt for AI Agents
In src/main/java/com/example/umc9th/domain/review/service/ReviewServiceImpl.java
around lines 96 to 101 (createReview validates store existence at lines 49-50),
add the same store existence check before querying reviews: call the store
repository (e.g., storeRepository.existsById(storeId) or findById) and if the
store does not exist throw the same NotFound/StoreNotFoundException used
elsewhere; only then proceed to fetch the Slice of reviews so callers can
distinguish "store not found" from "no reviews".

@coderabbitai
Copy link

coderabbitai bot commented Nov 25, 2025

@Yujin1219: I'll review the changes in this PR for you.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

@ggamnunq ggamnunq changed the title [✨ Feat] 9주차-API & Paging [✨ Feat] 10주차-API & Paging Dec 23, 2025
@ggamnunq ggamnunq removed a link to an issue Dec 23, 2025
5 tasks
@ggamnunq ggamnunq linked an issue Dec 23, 2025 that may be closed by this pull request
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[✨ Feat] 10주차-로그인 및 회원 가입

3 participants