-
Notifications
You must be signed in to change notification settings - Fork 0
[FEAT] 가까운 매장 조회 api #111
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
[FEAT] 가까운 매장 조회 api #111
Conversation
|
Caution Review failedThe pull request is closed. Walkthrough요청 DTO를 Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Controller
participant Service
participant Repository
participant DB
Client->>Controller: POST /restaurants/nearby { lat, lon }
activate Controller
Controller->>Service: getNearByRestaurants(UserLocationRequest)
activate Service
alt 위치 제공됨
Service->>Repository: findNearbyRestaurantsWithinRadius(lat, lon, 3000)
activate Repository
Repository->>DB: ST_Distance_Sphere 쿼리(위치 기반 필터)
DB-->>Repository: RestaurantDistanceProjection[]
Repository-->>Service: 목록(거리, 식당Id, 북마크 등)
Service->>Service: homeRestaurantResponseMapper 매핑(거리 포함)
Service-->>Controller: List<GetHomeRestaurantResponse>
else 위치 미제공
Service-->>Controller: LOCATION_REQUIRED 예외 발생
end
deactivate Service
Controller-->>Client: BaseResponse<List<GetHomeRestaurantResponse>>
deactivate Controller
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
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. Comment |
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
🤖 Fix all issues with AI Agents
In
@src/main/java/konkuk/corkCharge/global/response/status/BaseExceptionResponseStatus.java:
- Around line 30-32: The comment for LOCATION_REQUIRED in class
BaseExceptionResponseStatus is written as a malformed Javadoc
(`/**LOCATION_REQUIRED`) — replace it with a properly formed comment above the
LOCATION_REQUIRED constant (either a proper Javadoc block like `/** ... */`
containing "LOCATION_REQUIRED" and "70000 : User" or a simple block/line
comment) so it closes correctly and follows Javadoc format; update the comment
text near the LOCATION_REQUIRED symbol in BaseExceptionResponseStatus
accordingly.
🧹 Nitpick comments (2)
src/main/java/konkuk/corkCharge/domain/restaurant/dto/request/UserLocationRequest.java (1)
3-10: 좌표 범위 검증 추가를 권장합니다.위도와 경도 필드에 유효 범위 검증이 없습니다. 잘못된 좌표 값이 전달되면 거리 계산 시 예상치 못한 결과가 발생할 수 있습니다.
🔎 제안하는 수정안
+import jakarta.validation.constraints.DecimalMax; +import jakarta.validation.constraints.DecimalMin; + public record UserLocationRequest( + @DecimalMin(value = "-90.0", message = "위도는 -90 이상이어야 합니다.") + @DecimalMax(value = "90.0", message = "위도는 90 이하여야 합니다.") Double lat, + @DecimalMin(value = "-180.0", message = "경도는 -180 이상이어야 합니다.") + @DecimalMax(value = "180.0", message = "경도는 180 이하여야 합니다.") Double lon ) {src/main/java/konkuk/corkCharge/domain/restaurant/service/RestaurantService.java (1)
332-348: 구현이 적절합니다.위치 필수 검증과 반경 내 매장 조회 로직이 올바르게 구현되어 있습니다.
성능 관련 참고사항:
restaurantSummaryService.getSummary(id)호출이 각 레스토랑마다 수행되어 N+1 쿼리 패턴이 발생할 수 있습니다. 현재는 기존 코드 패턴을 따르고 있으나, 조회 결과가 많아질 경우 배치 조회 방식으로의 리팩토링을 고려해 볼 수 있습니다.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/main/java/konkuk/corkCharge/domain/restaurant/controller/RestaurantController.javasrc/main/java/konkuk/corkCharge/domain/restaurant/dto/request/UserLocationRequest.javasrc/main/java/konkuk/corkCharge/domain/restaurant/repository/RestaurantRepository.javasrc/main/java/konkuk/corkCharge/domain/restaurant/service/RestaurantService.javasrc/main/java/konkuk/corkCharge/global/config/SecurityConfig.javasrc/main/java/konkuk/corkCharge/global/response/status/BaseExceptionResponseStatus.java
⏰ 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: build
🔇 Additional comments (7)
src/main/java/konkuk/corkCharge/global/config/SecurityConfig.java (1)
50-57: LGTM!새로운
/restaurants/nearby엔드포인트가 적절하게 공개 접근 가능한 엔드포인트로 설정되었습니다. 기존 패턴과 일관성 있게 구현되었습니다.src/main/java/konkuk/corkCharge/global/response/status/BaseExceptionResponseStatus.java (1)
28-28: LGTM!사용자 위치 필수 검증을 위한 새로운 에러 코드가 적절하게 추가되었습니다. 에러 메시지도 명확합니다.
src/main/java/konkuk/corkCharge/domain/restaurant/repository/RestaurantRepository.java (1)
47-48: LGTM!주석에 설명을 추가하여 각 메서드의 용도가 더 명확해졌습니다.
Also applies to: 50-50
src/main/java/konkuk/corkCharge/domain/restaurant/controller/RestaurantController.java (2)
76-81: LGTM!요청 DTO 타입이
UserLocationRequest로 일관성 있게 변경되었습니다. 기존 API 계약을 유지하면서 더 명확한 네이밍을 적용했습니다.
90-95: 서비스 레이어의 위치 검증이 올바르게 구현되어 있습니다.
RestaurantService.getNearByRestaurants메서드에서req == null || !req.hasUserLocation()검증을 통해 위치 정보를 확인하고, 위치가 없을 경우CustomException(LOCATION_REQUIRED)예외를 발생시킵니다. 엔드포인트 구현이 정확합니다.src/main/java/konkuk/corkCharge/domain/restaurant/service/RestaurantService.java (2)
37-38: LGTM!3km 반경을 상수로 정의한 것은 좋은 관행입니다. 유지보수성과 가독성이 향상됩니다.
259-294: LGTM!사용자 위치 유무에 따른 분기 처리가 명확하고, 거리 정보를 포함한 응답 매핑이 적절하게 구현되어 있습니다.
| // 사용자 위치 기준 3Km 이내에 있는 모든 매장 : 가까운 매장 리스트 | ||
| @Query(value = """ | ||
| SELECT | ||
| r.restaurant_id AS restaurantId, | ||
| ROUND( | ||
| ST_Distance_Sphere( | ||
| r.location, | ||
| ST_SRID(POINT(:lon, :lat), 4326) | ||
| ) / 1000, | ||
| 1 | ||
| ) AS distanceKm | ||
| FROM restaurant r | ||
| WHERE r.has_corkage = 1 | ||
| AND ST_X(r.location) != 0 | ||
| AND ST_Y(r.location) != 0 | ||
| AND ST_Distance_Sphere( | ||
| r.location, | ||
| ST_SRID(POINT(:lon, :lat), 4326) | ||
| ) <= :radiusMeters | ||
| ORDER BY distanceKm ASC, r.bookmark_count DESC | ||
| """, nativeQuery = true) | ||
| List<RestaurantDistanceProjection> findNearbyRestaurantsWithinRadius( | ||
| @Param("lat") double lat, | ||
| @Param("lon") double lon, | ||
| @Param("radiusMeters") int radiusMeters | ||
| ); |
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 | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
# 데이터베이스 마이그레이션, 스키마 파일 위치 파악
find . -type f \( -name "*.sql" -o -name "*schema*" -o -name "*migration*" -o -name "*flyway*" \) | head -20Repository: CorkCharge/CorkCharge-BE
Length of output: 50
🏁 Script executed:
# restaurant 테이블 관련 SQL 파일 찾기
rg -l "restaurant" --type sqlRepository: CorkCharge/CorkCharge-BE
Length of output: 216
🏁 Script executed:
# restaurant 테이블 생성 및 인덱스 관련 SQL 검색
rg -n "CREATE TABLE.*restaurant|CREATE.*INDEX.*restaurant|CREATE.*SPATIAL.*INDEX" --type sql -A5 -B2Repository: CorkCharge/CorkCharge-BE
Length of output: 216
🏁 Script executed:
# Repository 구조 파악
git ls-files | head -30Repository: CorkCharge/CorkCharge-BE
Length of output: 1549
🏁 Script executed:
# Restaurant 엔티티 클래스 찾기
find . -type f -name "*Restaurant*.java" | grep -E "(entity|domain)" | head -10Repository: CorkCharge/CorkCharge-BE
Length of output: 977
🏁 Script executed:
# 데이터베이스 관련 설정 파일 찾기
find . -type f \( -name "application*.yml" -o -name "application*.properties" -o -name "*.sql" \) 2>/dev/nullRepository: CorkCharge/CorkCharge-BE
Length of output: 104
🏁 Script executed:
# Restaurant 엔티티에 인덱스 관련 주석/애너테이션 확인
rg -n "@Index|@Table|location" --type java -i | grep -i restaurant | head -20Repository: CorkCharge/CorkCharge-BE
Length of output: 2840
🏁 Script executed:
# Restaurant 엔티티 클래스 전체 내용 확인
cat -n src/main/java/konkuk/corkCharge/domain/restaurant/domain/Restaurant.javaRepository: CorkCharge/CorkCharge-BE
Length of output: 3844
🏁 Script executed:
# RestaurantRepository 전체 내용 확인
cat -n src/main/java/konkuk/corkCharge/domain/restaurant/repository/RestaurantRepository.javaRepository: CorkCharge/CorkCharge-BE
Length of output: 5265
🏁 Script executed:
# 데이터베이스 설정 확인
cat -n src/main/resources/application.ymlRepository: CorkCharge/CorkCharge-BE
Length of output: 3986
공간 인덱스를 추가하여 거리 계산 성능을 개선하세요.
ST_Distance_Sphere 함수가 SELECT 절(104-107행)과 WHERE 절(114-117행)에서 각각 한 번씩, 총 두 번 호출됩니다. MySQL의 제약으로 SELECT 절의 별칭을 동일 쿼리의 WHERE 절에서 사용할 수 없어 불가피한 중복이지만, 현재 location 컬럼에 공간 인덱스가 정의되어 있지 않기 때문에 성능 저하가 발생할 수 있습니다.
Restaurant.java에서 location 컬럼이 정의되어 있으나 공간 인덱스가 누락되어 있습니다. Hibernate 스키마 관리(ddl-auto: update) 환경에서 공간 인덱스를 추가하려면 다음과 같이 @Index 애너테이션을 사용하여 명시적으로 정의해야 합니다:
@Column(
name = "location",
columnDefinition = "POINT SRID 4326 NOT NULL",
insertable = false,
updatable = false
)
@Index(name = "idx_restaurant_location", columnDefinition = "location")
private Point location;또는 JPA native 쿼리를 통해 별도로 인덱스를 생성할 수 있습니다.
| /**LOCATION_REQUIRED | ||
| * 70000 : User | ||
| */ |
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.
주석 형식 오류를 수정해주세요.
Line 30의 주석이 /**LOCATION_REQUIRED로 잘못 작성되어 있습니다. 올바른 Javadoc 형식으로 수정이 필요합니다.
🔎 제안하는 수정안
- /**LOCATION_REQUIRED
+ /**
* 70000 : User
*/📝 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.
| /**LOCATION_REQUIRED | |
| * 70000 : User | |
| */ | |
| /** | |
| * 70000 : User | |
| */ |
🤖 Prompt for AI Agents
In
@src/main/java/konkuk/corkCharge/global/response/status/BaseExceptionResponseStatus.java
around lines 30 - 32, The comment for LOCATION_REQUIRED in class
BaseExceptionResponseStatus is written as a malformed Javadoc
(`/**LOCATION_REQUIRED`) — replace it with a properly formed comment above the
LOCATION_REQUIRED constant (either a proper Javadoc block like `/** ... */`
containing "LOCATION_REQUIRED" and "70000 : User" or a simple block/line
comment) so it closes correctly and follows Javadoc format; update the comment
text near the LOCATION_REQUIRED symbol in BaseExceptionResponseStatus
accordingly.
#️⃣연관된 이슈
#110
📝작업 내용
💬리뷰 요구사항(선택)
Summary by CodeRabbit
릴리즈 노트
✏️ Tip: You can customize this high-level summary in your review settings.