Skip to content

Conversation

@leegwichan
Copy link
Member

@leegwichan leegwichan commented Jul 24, 2025

✨ 개요

  • 가게 상세 페이지에서 사용할 '가게 이미지 조회 API' 구현
  • 자세한 사항은 관련 이슈 참고 부탁드립니다!

🧾 관련 이슈

closed #98

🔍 참고 사항 (선택)

Summary by CodeRabbit

  • 신규 기능

    • 음식점의 이미지 목록을 조회할 수 있는 API 엔드포인트(/api/shops/{storeId}/images)가 추가되었습니다. 해당 엔드포인트를 통해 음식점에 등록된 이미지 URL 리스트를 확인할 수 있습니다.
  • 버그 수정

    • 해당 없음
  • 문서화

    • 음식점 이미지 조회 API에 대한 테스트 및 REST Docs 문서가 추가되어, 요청 및 응답 형식이 명확하게 안내됩니다.
  • 테스트

    • 음식점 이미지 조회 기능에 대한 다양한 단위 및 통합 테스트가 추가되어, 이미지가 있을 때와 없을 때, 존재하지 않는 음식점 요청 시의 동작이 검증됩니다.

@coderabbitai
Copy link

coderabbitai bot commented Jul 24, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

가게에 달린 응원 이미지들을 조회하는 새로운 API가 추가되었습니다. 이를 위해 컨트롤러, 서비스, 레포지토리, DTO가 신설 및 확장되었으며, 이에 대한 단위 테스트, 통합 테스트, 문서화 테스트가 함께 도입되었습니다.

Changes

Cohort / File(s) Change Summary
ImagesResponse DTO 추가
src/main/java/eatda/controller/store/ImagesResponse.java
가게 이미지 URL 목록을 담는 불변 record ImagesResponse 신설
StoreController 확장
src/main/java/eatda/controller/store/StoreController.java
/api/shops/{storeId}/images GET 엔드포인트 및 핸들러 메서드 추가
CheerRepository 확장
src/main/java/eatda/repository/store/CheerRepository.java
JPA 레포지토리 상속, 모든 이미지 키 조회 메서드(findAllImageKey) 추가
StoreService 확장
src/main/java/eatda/service/store/StoreService.java
가게 이미지 URL 리스트 반환 메서드(getStoreImages) 추가
컨트롤러 테스트 추가
src/test/java/eatda/controller/store/StoreControllerTest.java
이미지 조회 API 정상/빈 결과 테스트 케이스 추가
API 문서화 및 실패 케이스 테스트
src/test/java/eatda/document/store/StoreDocumentTest.java
성공/실패 케이스 문서화 및 테스트, REST Docs 문서 추가
CheerRepository 테스트 확장
src/test/java/eatda/repository/store/CheerRepositoryTest.java
모든 이미지 키 조회 관련 테스트 케이스 추가
서비스 테스트 추가
src/test/java/eatda/service/store/StoreServiceTest.java
가게 이미지 조회 정상/빈/예외 케이스 테스트 케이스 추가

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant StoreController
    participant StoreService
    participant CheerRepository
    participant ImageStorage

    Client->>StoreController: GET /api/shops/{storeId}/images
    StoreController->>StoreService: getStoreImages(storeId)
    StoreService->>CheerRepository: findAllImageKey(store)
    CheerRepository-->>StoreService: List<ImageKey>
    loop for each imageKey
        StoreService->>ImageStorage: getPresignedUrl(imageKey)
        ImageStorage-->>StoreService: String (imageUrl)
    end
    StoreService-->>StoreController: ImagesResponse(List<String> imageUrls)
    StoreController-->>Client: 200 OK + ImagesResponse
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
특정 가게에 달린 응원의 이미지들을 조회하는 API 구현 (#98)

Assessment against linked issues: Out-of-scope changes

(해당 변경사항에서 범위 밖의 변경은 발견되지 않았습니다.)

Suggested labels

released on @beta

Suggested reviewers

  • lvalentine6

Poem

🐰
가게마다 응원 사진,
이제 쉽게 볼 수 있지!
새로운 API로 척척,
이미지는 쏙쏙쏙!
테스트도 꼼꼼하게,
문서화도 빠짐없이~
오늘도 토끼는 신나게!

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 706a5f8 and d886c55.

📒 Files selected for processing (5)
  • src/main/java/eatda/controller/store/StoreController.java (1 hunks)
  • src/main/java/eatda/service/store/StoreService.java (2 hunks)
  • src/test/java/eatda/controller/store/StoreControllerTest.java (1 hunks)
  • src/test/java/eatda/document/store/StoreDocumentTest.java (5 hunks)
  • src/test/java/eatda/service/store/StoreServiceTest.java (2 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/PRODUCT-197

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 0

🧹 Nitpick comments (1)
src/main/java/eatda/controller/store/StoreController.java (1)

20-23: REST API 엔드포인트가 적절히 구현되었습니다.

RESTful 패턴을 잘 따르고 있으며 서비스 계층으로의 위임도 적절합니다.

입력 검증을 위해 @PathVariable@Positive 어노테이션 추가를 고려해보세요:

-public ResponseEntity<ImagesResponse> getStoreImages(@PathVariable long storeId) {
+public ResponseEntity<ImagesResponse> getStoreImages(@PathVariable @Positive long storeId) {
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 48ad47d and 706a5f8.

📒 Files selected for processing (9)
  • src/main/java/eatda/controller/store/ImagesResponse.java (1 hunks)
  • src/main/java/eatda/controller/store/StoreController.java (2 hunks)
  • src/main/java/eatda/repository/store/CheerRepository.java (2 hunks)
  • src/main/java/eatda/repository/store/StoreRepository.java (1 hunks)
  • src/main/java/eatda/service/store/StoreService.java (2 hunks)
  • src/test/java/eatda/controller/store/StoreControllerTest.java (1 hunks)
  • src/test/java/eatda/document/store/StoreDocumentTest.java (2 hunks)
  • src/test/java/eatda/repository/store/CheerRepositoryTest.java (3 hunks)
  • src/test/java/eatda/service/store/StoreServiceTest.java (2 hunks)
🧰 Additional context used
🧠 Learnings (2)
src/main/java/eatda/service/store/StoreService.java (2)

Learnt from: leegwichan
PR: #60
File: src/main/java/eatda/client/map/MapClient.java:24-41
Timestamp: 2025-07-09T07:54:18.446Z
Learning: In MapClient.java, the developer prefers to keep Kakao API-specific values (baseUrl, pageSize) hardcoded rather than extracting them to configuration properties, as these values are inherently tied to the Kakao API specification.

Learnt from: leegwichan
PR: #90
File: src/main/java/eatda/service/store/CheerService.java:35-46
Timestamp: 2025-07-20T05:38:13.430Z
Learning: CheerService에서 각 컴포넌트(storeSearchFilter, memberRepository, imageService)들이 자신의 책임 범위 내에서 검증을 수행하므로 서비스 레이어에서 추가적인 중복 검증이 불필요함. 각 레이어의 책임 분리가 잘 되어 있는 구조.

src/test/java/eatda/service/store/StoreServiceTest.java (1)

Learnt from: leegwichan
PR: #60
File: src/test/java/eatda/controller/store/StoreControllerTest.java:10-32
Timestamp: 2025-07-09T07:56:50.612Z
Learning: 컨트롤러 테스트에서 MockitoBean으로 의존성을 모킹한 경우, 상세한 비즈니스 로직 검증보다는 컨트롤러 계층의 동작(라우팅, 파라미터 처리, 응답 구조 등)을 검증하는 것이 더 적절합니다. 모킹된 데이터에 대한 상세 검증은 의미가 없기 때문입니다.

🧬 Code Graph Analysis (1)
src/test/java/eatda/document/store/StoreDocumentTest.java (1)
src/test/java/eatda/controller/store/StoreControllerTest.java (3)
  • Nested (15-49)
  • Nested (51-80)
  • Nested (82-100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (17)
src/main/java/eatda/controller/store/ImagesResponse.java (1)

5-6: 깔끔한 레코드 정의입니다.

이미지 URL 목록을 담는 응답 DTO로 적절하게 구현되었습니다. 레코드를 사용한 불변 데이터 전달 객체로서 간결하고 명확합니다.

src/main/java/eatda/service/store/StoreService.java (1)

32-39: 가게 이미지 조회 로직이 잘 구현되었습니다.

메서드 구현이 명확하고 효율적입니다:

  • storeRepository.getById()를 통한 적절한 예외 처리
  • 스트림을 활용한 깔끔한 데이터 변환
  • 메서드 참조 사용으로 가독성 향상
src/test/java/eatda/service/store/StoreServiceTest.java (1)

26-60: 포괄적인 테스트 커버리지를 제공합니다.

세 가지 시나리오를 모두 적절히 테스트하고 있습니다:

  • 정상 케이스: 여러 이미지 존재 시
  • 엣지 케이스: 이미지가 없는 경우
  • 예외 케이스: 존재하지 않는 가게 ID

테스트 구조와 검증 로직이 명확하고 적절합니다.

src/test/java/eatda/controller/store/StoreControllerTest.java (1)

15-49: 컨트롤러 테스트가 적절히 구현되었습니다.

REST Assured를 활용한 HTTP 테스트가 잘 구성되어 있으며, 컨트롤러 계층의 동작(라우팅, 응답 구조, 상태 코드)을 적절히 검증하고 있습니다. 이미지가 있는 경우와 없는 경우 모두 커버하여 좋은 테스트 커버리지를 제공합니다.

src/test/java/eatda/repository/store/CheerRepositoryTest.java (3)

9-9: LGTM!

새로운 findAllImageKey 메서드 테스트를 위해 필요한 import 추가입니다.


30-32: 테스트 가독성 개선

ImageKey 객체 전체를 비교하는 대신 실제 값을 추출하여 비교하도록 개선되었습니다. 테스트의 의도가 더 명확해졌습니다.


49-80: 새로운 findAllImageKey 메서드에 대한 포괄적인 테스트

새로운 findAllImageKey 메서드에 대해 성공 케이스와 빈 결과 케이스를 모두 적절히 테스트하고 있습니다. 테스트 구조와 assertion이 올바르게 작성되었습니다.

참고: Thread.sleep(5)는 테스트에서 순서를 보장하기 위한 일반적인 방법이지만, 테스트 실행 시간을 늘리고 가끔 불안정할 수 있습니다. 현재 상황에서는 허용 가능하지만, 향후 더 나은 대안(예: 명시적인 시간 설정)을 고려해볼 수 있습니다.

src/main/java/eatda/repository/store/StoreRepository.java (3)

11-11: JpaRepository로 마이그레이션 - 좋은 개선사항

Repository에서 JpaRepository로 변경하여 표준 CRUD 메서드들을 상속받도록 개선되었습니다. 명시적인 save 메서드 선언이 불필요해졌고, Spring Data JPA 컨벤션을 따릅니다.


4-5: 필요한 import 추가

새로운 getById 메서드의 예외 처리와 JpaRepository 상속을 위해 필요한 import들이 적절히 추가되었습니다.

Also applies to: 9-9


13-17: 도메인별 예외 처리를 제공하는 잘 구현된 메서드

findById를 사용하여 Optional을 적절한 도메인 예외로 변환하는 표준적인 패턴을 따릅니다. STORE_NOT_FOUND 에러 코드를 사용한 예외 처리가 적절합니다.

src/main/java/eatda/repository/store/CheerRepository.java (3)

13-13: StoreRepository와 일관된 JpaRepository 마이그레이션

Repository에서 JpaRepository로 변경하여 표준 CRUD 메서드들을 상속받도록 개선되었습니다. StoreRepository와 동일한 패턴을 따라 일관성이 유지됩니다.


10-10: JpaRepository 상속을 위한 필요한 import

JpaRepository 상속을 위해 필요한 import가 적절히 추가되었습니다.


24-28: 기존 메서드와 일관된 새로운 쿼리 메서드

findRecentImageKey와 유사한 패턴을 따르면서 모든 이미지 키를 반환하는 메서드입니다. JPQL 쿼리가 올바르게 작성되었고, 정렬 순서와 필터링 조건이 기존 메서드와 일관됩니다.

src/test/java/eatda/document/store/StoreDocumentTest.java (4)

15-15: 새로운 API 응답 타입을 위한 import 추가

새로운 가게 이미지 조회 API의 응답 타입인 ImagesResponse를 위한 필요한 import입니다.


39-49: 적절한 REST Docs 문서화 설정

요청/응답 문서화가 다른 엔드포인트들과 일관된 패턴을 따르고 있습니다. path parameter와 response field에 대한 설명이 명확합니다.


51-71: 성공 케이스에 대한 적절한 테스트

서비스 레이어를 적절히 모킹하고 REST Docs 문서화를 포함한 통합 테스트가 잘 작성되었습니다. 실제적인 예시 데이터를 사용하여 테스트합니다.


73-89: 에러 케이스에 대한 포괄적인 테스트

STORE_NOT_FOUND 에러에 대한 매개변수화된 테스트가 적절히 구현되었습니다. 서비스 예외를 모킹하고 올바른 상태 코드를 검증합니다.

Copy link
Member

@lvalentine6 lvalentine6 left a comment

Choose a reason for hiding this comment

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

이번 PR도 고생하셨습니다! 🎉
LGTM!

# Conflicts:
#	src/main/java/eatda/service/store/StoreService.java
#	src/test/java/eatda/controller/store/StoreControllerTest.java
#	src/test/java/eatda/document/store/StoreDocumentTest.java
#	src/test/java/eatda/service/store/StoreServiceTest.java
@leegwichan leegwichan merged commit ec732e5 into develop Jul 28, 2025
2 of 3 checks passed
@leegwichan leegwichan deleted the feat/PRODUCT-197 branch July 28, 2025 11:12
@sonarqubecloud
Copy link

@github-actions
Copy link

🎉 This PR is included in version 1.4.0-develop.31 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@github-actions
Copy link

🎉 This PR is included in version 1.5.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[PRODUCT-197] [Feat] 가게 이미지 조회 API 구현

3 participants