-
Notifications
You must be signed in to change notification settings - Fork 1
[Hot fix] 웨이블존 상세 정보 대표 이미지 조회 오류 해결 #178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Walkthrough세 곳의 서비스에서 MySQL 전용 리포지토리 참조를 주석 처리했다. WaybleZoneService의 상세 조회에서 대표 이미지 선택 로직을 첫 번째 이미지 기반에서 zone.getMainImageUrl() 사용으로 변경했다. 퍼블릭 API 시그니처 변화는 없다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Client
participant Controller as WaybleZoneController
participant Service as WaybleZoneService
participant Repo as WaybleZoneRepository
Client->>Controller: GET /zones/{id}
Controller->>Service: getWaybleZoneDetail(id)
Service->>Repo: findById(id)
Repo-->>Service: WaybleZone (images, mainImageUrl, ...)
rect rgba(200, 230, 255, 0.3)
note over Service: 대표 이미지 선택 로직 (변경)
Service->>Service: imageUrl = zone.getMainImageUrl()
end
Service->>Service: photoUrls = images.map(url)
Service-->>Controller: WaybleZoneDetailResponseDto(imageUrl, photoUrls, ...)
Controller-->>Client: 200 OK + JSON
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (7)
src/main/java/com/wayble/server/explore/service/WaybleZoneRecommendService.java (2)
7-7: 주석 처리된 MySQL 전용 리포지토리 import는 정리하거나 프로필 기반 주입으로 전환 권장주석으로 유지하면 드리프트 위험이 큽니다.
@Profile또는@ConditionalOnProperty로 런타임에 선택 주입하거나, 불필요하면 제거하세요. 동일 변수명을 가진 대안 구현을 주입해야 한다면 공통 인터페이스로 추상화하는 것도 고려해 주세요.
30-31: 주석 처리된 필드 선언 제거 또는 조건부 빈으로 관리죽은 코드가 클래스 가독성을 떨어뜨립니다. 운영 중 MySQL 구현을 재도입할 계획이 없다면 삭제하고, 환경별 선택이 필요하다면
WaybleZoneQueryRecommendRepository와 MySQL 구현을 공통 포트(예:WaybleZoneRecommendPort)로 추상화해@Profile("mysql"),@Profile("es")로 전환 가능하게 만드는 것이 깔끔합니다.src/main/java/com/wayble/server/explore/service/WaybleFacilityDocumentService.java (2)
5-5: 주석 import 정리의도적으로 보관할 이유가 없다면 주석 import는 제거하는 편이 유지보수에 유리합니다. 환경별 전환이 필요하면
@Profile기반으로 분리해 주세요.
20-21: 대체 구현( MySQL ) 주입은 조건부 빈/프로필로 전환주석 필드는 IDE 탐색성/정적 분석 품질을 떨어뜨립니다. 공통 포트 인터페이스로 추상화한 뒤 프로필로 스위칭하는 방향을 권장합니다.
src/main/java/com/wayble/server/explore/service/WaybleZoneSearchService.java (2)
4-4: 주석 처리된 MySQL 검색 리포지토리 import 정리불필요한 주석 import는 제거하거나, 환경 전환 필요 시
@Profile사용으로 명확히 관리하세요.
22-23: 주석 필드 대신 인터페이스 + 프로필로 전환 권장검색 리포지토리도 공통 인터페이스를 두고 ES/MySQL 구현을 분리하여 런타임에 선택 주입하면 주석 토글 없이 깔끔하게 운영할 수 있습니다.
src/main/java/com/wayble/server/wayblezone/service/WaybleZoneService.java (1)
72-72: 죽은 코드(주석 라인) 정리기존 첫 이미지 기반 로직은 더 이상 사용되지 않습니다. 혼선을 줄이기 위해 주석 라인은 제거하는 것을 권장합니다. 히스토리는 Git이 보존합니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
src/main/java/com/wayble/server/explore/service/WaybleFacilityDocumentService.java(2 hunks)src/main/java/com/wayble/server/explore/service/WaybleZoneRecommendService.java(2 hunks)src/main/java/com/wayble/server/explore/service/WaybleZoneSearchService.java(2 hunks)src/main/java/com/wayble/server/wayblezone/service/WaybleZoneService.java(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
src/main/java/com/wayble/server/explore/service/WaybleZoneRecommendService.java (1)
src/main/java/com/wayble/server/explore/repository/recommend/WaybleZoneQueryRecommendRepository.java (1)
Repository(30-163)
src/main/java/com/wayble/server/explore/service/WaybleFacilityDocumentService.java (2)
src/main/java/com/wayble/server/explore/repository/facility/WaybleFacilityQuerySearchRepository.java (1)
Repository(20-101)src/main/java/com/wayble/server/explore/repository/facility/WaybleFacilityDocumentRepository.java (1)
WaybleFacilityDocumentRepository(8-10)
src/main/java/com/wayble/server/wayblezone/service/WaybleZoneService.java (5)
src/main/java/com/wayble/server/wayblezone/entity/WaybleZone.java (2)
updateMainImageUrl(128-131)setMainImageUrl(86-89)src/main/java/com/wayble/server/wayblezone/dto/WaybleZoneListResponseDto.java (1)
Builder(6-17)src/main/java/com/wayble/server/wayblezone/dto/WaybleZoneDetailResponseDto.java (1)
Builder(9-30)src/main/java/com/wayble/server/wayblezone/entity/WaybleZoneImage.java (1)
Entity(9-29)src/main/java/com/wayble/server/admin/repository/AdminWaybleZoneRepositoryImpl.java (1)
Override(53-105)
src/main/java/com/wayble/server/explore/service/WaybleZoneSearchService.java (3)
src/main/java/com/wayble/server/wayblezone/repository/WaybleZoneRepository.java (1)
WaybleZoneRepository(12-34)src/main/java/com/wayble/server/wayblezone/repository/WaybleZoneRepositoryCustom.java (1)
WaybleZoneRepositoryCustom(9-18)src/main/java/com/wayble/server/explore/repository/search/WaybleZoneQuerySearchRepository.java (1)
Repository(24-278)
| var images = zone.getWaybleZoneImageList(); | ||
| String imageUrl = images.stream().findFirst().map(WaybleZoneImage::getImageUrl).orElse(null); | ||
| //String imageUrl = images.stream().findFirst().map(WaybleZoneImage::getImageUrl).orElse(null); | ||
| List<String> photoUrls = images.stream().map(WaybleZoneImage::getImageUrl).toList(); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
대표 이미지 null 폴백 및 photos와의 불일치 해소 필요
이번 수정으로 상세의 대표 이미지를 zone.getMainImageUrl()로 일관화한 점은 👍 입니다. 다만 기존 데이터에 mainImageUrl이 비어 있는 경우 상세 화면의 대표 이미지가 사라질 수 있고, 대표 이미지가 waybleZoneImageList에 포함되지 않은 경우 photos와 대표 이미지가 불일치할 수 있습니다. 아래처럼 폴백(첫 번째 이미지)과 photos에 대표 이미지 포함을 보장하는 처리를 제안합니다.
아래 diff는 해당 구간만 교체합니다.
@@
- var images = zone.getWaybleZoneImageList();
- //String imageUrl = images.stream().findFirst().map(WaybleZoneImage::getImageUrl).orElse(null);
- List<String> photoUrls = images.stream().map(WaybleZoneImage::getImageUrl).toList();
+ var images = zone.getWaybleZoneImageList();
+ // 대표 이미지(없으면 첫 이미지로 폴백) + photos에 대표 이미지 포함 보장
+ String mainImageUrl = zone.getMainImageUrl();
+ List<String> photoUrls = images.stream()
+ .map(WaybleZoneImage::getImageUrl)
+ .filter(java.util.Objects::nonNull)
+ .distinct()
+ .collect(java.util.stream.Collectors.toCollection(java.util.ArrayList::new));
+ if (mainImageUrl == null || mainImageUrl.isBlank()) {
+ mainImageUrl = photoUrls.isEmpty() ? null : photoUrls.get(0);
+ } else if (!photoUrls.contains(mainImageUrl)) {
+ photoUrls.add(0, mainImageUrl);
+ }
@@
- .imageUrl(zone.getMainImageUrl())
+ .imageUrl(mainImageUrl)추가 import가 필요합니다(파일 상단 import 블록에 추가).
import java.util.ArrayList;
import java.util.Objects;
import java.util.stream.Collectors;Also applies to: 97-97
🤖 Prompt for AI Agents
In src/main/java/com/wayble/server/wayblezone/service/WaybleZoneService.java
around lines 71-74 (also apply same change at line 97), the code builds
photoUrls directly from zone.getWaybleZoneImageList() and uses
zone.getMainImageUrl() elsewhere, which can lead to a null main image and
mismatches between the representative image and photos; update the logic to (1)
if zone.getMainImageUrl() is null or blank, set it to the first imageUrl from
waybleZoneImageList (fallback), (2) build photoUrls as a modifiable list, ensure
the mainImageUrl is included as the first element (avoid duplicates using
Objects.equals), and (3) import java.util.ArrayList, java.util.Objects, and
java.util.stream.Collectors at the top of the file. Ensure you perform the same
fix at the other occurrence around line 97.
| .reviewCount(zone.getReviewCount()) | ||
| .contactNumber(zone.getContactNumber()) | ||
| .imageUrl(imageUrl) | ||
| .imageUrl(zone.getMainImageUrl()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
목록 API와 대표 이미지 기준의 일관성 점검 요청
상세는 mainImageUrl, 목록은 여전히 "첫 이미지"를 노출합니다(라인 39~49). 사용자 경험 차원에서 동일 기준을 적용할지 결정이 필요합니다. 아래 스크립트로 코드베이스의 대표 이미지 사용 위치를 빠르게 점검해 주세요.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "[1] 목록/상세에서 대표 이미지 사용 위치 확인"
rg -n -C2 'getMainImageUrl\(|imageUrl\(' src/main/java/com/wayble/server/wayblezone | sed -n '1,200p'
echo
echo "[2] 추천/검색 응답 DTO에서 대표 이미지 필드 구성 확인"
rg -n -C2 'WaybleZone(Recommend|Search|List)ResponseDto|mainImageUrl' src/main/java | sed -n '1,200p'Length of output: 24783
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "===== WaybleZoneListResponseDto ====="
sed -n '1,200p' src/main/java/com/wayble/server/wayblezone/dto/WaybleZoneListResponseDto.java
echo
echo "===== WaybleZoneDetailResponseDto ====="
sed -n '1,200p' src/main/java/com/wayble/server/wayblezone/dto/WaybleZoneDetailResponseDto.java
echo
echo "===== WaybleZoneRecommendResponseDto ====="
sed -n '1,200p' src/main/java/com/wayble/server/explore/dto/recommend/WaybleZoneRecommendResponseDto.java
echo
echo "===== WaybleZoneSearchResponseDto ====="
sed -n '1,200p' src/main/java/com/wayble/server/explore/dto/search/response/WaybleZoneSearchResponseDto.javaLength of output: 3465
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "===== WaybleZoneInfoResponseDto (공통 DTO) ====="
sed -n '1,200p' src/main/java/com/wayble/server/explore/dto/common/WaybleZoneInfoResponseDto.java
echo
echo "===== UserPlaceService에서 대표 이미지 사용 확인 ====="
rg -n -A5 -B5 'imageUrl.*mainImageUrl|mainImageUrl.*imageUrl' src/main/java/com/wayble/server/user/service/UserPlaceService.javaLength of output: 1760
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "===== UserPlaceService snippet ====="
sed -n '100,160p' src/main/java/com/wayble/server/user/service/UserPlaceService.javaLength of output: 2710
대표 이미지 기준 일관성 필요: 리스트 API에서도 mainImageUrl 사용 제안
현재 코드베이스를 확인한 결과, 대표 이미지 노출 기준이 엔드포인트별로 상이합니다.
WaybleZoneService.getWaybleZones(src/main/java/com/wayble/server/wayblezone/service/WaybleZoneService.java:48)
• 리스트 응답에서로.imageUrl(image != null ? image.getImageUrl() : null)
zone.getWaybleZoneImageList().stream().findFirst()로 가져온 첫 번째 이미지를 사용- 그 외 엔드포인트
• 상세 응답(WaybleZoneDetailResponseDto.builder().imageUrl(zone.getMainImageUrl()))
• UserPlaceService.getZonesInPlace →.imageUrl(z.getMainImageUrl())
• 검색/추천 DTO (WaybleZoneInfoResponseDto의thumbnailImageUrl필드)
모두WaybleZone.mainImageUrl을 기준으로 노출
사용자 경험(UX)의 일관성을 위해, 리스트 API(getWaybleZones)에서도 zone.getMainImageUrl()을 사용하도록 수정할 것을 권고드립니다.
수정 예시(diff):
– .imageUrl(image != null ? image.getImageUrl() : null)
+ .imageUrl(zone.getMainImageUrl())- 대상 파일:
src/main/java/com/wayble/server/wayblezone/service/WaybleZoneService.java
(라인 48 기준)
🤖 Prompt for AI Agents
In src/main/java/com/wayble/server/wayblezone/service/WaybleZoneService.java
around line 48, the list API currently sets imageUrl from the first image in
waybleZoneImageList; change it to use zone.getMainImageUrl() instead to match
other endpoints (detail, UserPlaceService, search/recommendation) for consistent
UX; simply replace the conditional that uses the first image with
.imageUrl(zone.getMainImageUrl()), keeping null-safety if needed (no additional
transformation) so the list response aligns with the rest of the application.
✔️ 연관 이슈
📝 작업 내용
스크린샷 (선택)
Summary by CodeRabbit