Skip to content

Conversation

@jaepar
Copy link
Member

@jaepar jaepar commented Jan 6, 2026

#️⃣연관된 이슈

#110

📝작업 내용

사용자 위치 기준 3km 이내에 있는 매장들을 조회할 수 있도록 구현했습니다.

스크린샷 2026-01-06 오후 11 40 46

💬리뷰 요구사항(선택)

Summary by CodeRabbit

릴리즈 노트

  • 새로운 기능
    • 사용자 위치 기반 근처 음식점 검색 기능 추가 (반경 3km, 거리·북마크 우선 정렬)
  • 개선
    • 위치 기반 조회를 위한 요청 파라미터 구조 통일 및 거리 정보 포함 응답 강화
  • 오류 처리
    • 사용자 위치 미입력 시 반환되는 전용 오류 코드 추가
  • 보안/접근성
    • 근처 검색 엔드포인트에 대한 인증 예외 허용 추가

✏️ Tip: You can customize this high-level summary in your review settings.

@jaepar jaepar linked an issue Jan 6, 2026 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Jan 6, 2026

Caution

Review failed

The pull request is closed.

Walkthrough

요청 DTO를 GetNewRestaurantRequest에서 UserLocationRequest로 변경하고, 사용자 위치(위도·경도)를 받아 3km 반경 내 식당을 조회하는 /restaurants/nearby POST 엔드포인트 및 이를 지원하는 리포지토리·서비스 로직과 예외 코드를 추가했습니다.

Changes

Cohort / File(s) 변경 요약
요청 DTO 변경
src/main/java/konkuk/corkCharge/domain/restaurant/dto/request/UserLocationRequest.java
GetNewRestaurantRequest 레코드명을 UserLocationRequest로 변경(필드: lat, lon 유지)
컨트롤러 업데이트
src/main/java/konkuk/corkCharge/domain/restaurant/controller/RestaurantController.java
/restaurants/new 파라미터 타입을 UserLocationRequest로 교체; 새로운 /restaurants/nearby POST 엔드포인트 추가
서비스 로직 강화
src/main/java/konkuk/corkCharge/domain/restaurant/service/RestaurantService.java
getNewRestaurants(UserLocationRequest)로 시그니처 변경; getNearByRestaurants(UserLocationRequest) 추가; RADIUS_METERS = 3000 상수 추가; 매퍼명 변경 및 거리 기반 매핑 흐름 추가
저장소 확장
src/main/java/konkuk/corkCharge/domain/restaurant/repository/RestaurantRepository.java
findNearbyRestaurantsWithinRadius(double lat, double lon, int radiusMeters) 메서드 추가(반경 내 식당 거리 계산 및 정렬 쿼리 포함)
보안 설정 확대
src/main/java/konkuk/corkCharge/global/config/SecurityConfig.java
permitAll POST 경로에 /restaurants/nearby 추가
예외 상태 추가
src/main/java/konkuk/corkCharge/global/response/status/BaseExceptionResponseStatus.java
새 열거상수 LOCATION_REQUIRED(60006, "사용자 위치(좌표)값은 필수입니다.") 추가

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • simchaehyeon

Poem

🐰 내가 땅을 폴짝이며 좌표를 쫓아가요,
3km 안의 맛집들을 냄새로 찾아요.
위도와 경도가 있어야 길을 잃지 않죠,
가까운 순서로 줄지어, 북마크도 함께! 🍽️✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.15% 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 제목이 변경 사항의 핵심을 명확하게 반영합니다. 사용자 위치 기반 근처 매장 조회 API 추가라는 주요 기능을 간결하게 설명합니다.
Description check ✅ Passed PR 설명이 필수 섹션을 포함하고 있으며, 관련 이슈, 작업 내용, 스크린샷을 충분히 제공합니다.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e0f787b and a73a3f1.

📒 Files selected for processing (1)
  • src/main/java/konkuk/corkCharge/global/response/status/BaseExceptionResponseStatus.java

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

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 59757b3 and e0f787b.

📒 Files selected for processing (6)
  • src/main/java/konkuk/corkCharge/domain/restaurant/controller/RestaurantController.java
  • src/main/java/konkuk/corkCharge/domain/restaurant/dto/request/UserLocationRequest.java
  • src/main/java/konkuk/corkCharge/domain/restaurant/repository/RestaurantRepository.java
  • src/main/java/konkuk/corkCharge/domain/restaurant/service/RestaurantService.java
  • src/main/java/konkuk/corkCharge/global/config/SecurityConfig.java
  • src/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!

사용자 위치 유무에 따른 분기 처리가 명확하고, 거리 정보를 포함한 응답 매핑이 적절하게 구현되어 있습니다.

Comment on lines +99 to +124
// 사용자 위치 기준 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
);
Copy link

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 -20

Repository: CorkCharge/CorkCharge-BE

Length of output: 50


🏁 Script executed:

# restaurant 테이블 관련 SQL 파일 찾기
rg -l "restaurant" --type sql

Repository: 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 -B2

Repository: CorkCharge/CorkCharge-BE

Length of output: 216


🏁 Script executed:

# Repository 구조 파악
git ls-files | head -30

Repository: CorkCharge/CorkCharge-BE

Length of output: 1549


🏁 Script executed:

# Restaurant 엔티티 클래스 찾기
find . -type f -name "*Restaurant*.java" | grep -E "(entity|domain)" | head -10

Repository: CorkCharge/CorkCharge-BE

Length of output: 977


🏁 Script executed:

# 데이터베이스 관련 설정 파일 찾기
find . -type f \( -name "application*.yml" -o -name "application*.properties" -o -name "*.sql" \) 2>/dev/null

Repository: CorkCharge/CorkCharge-BE

Length of output: 104


🏁 Script executed:

# Restaurant 엔티티에 인덱스 관련 주석/애너테이션 확인
rg -n "@Index|@Table|location" --type java -i | grep -i restaurant | head -20

Repository: CorkCharge/CorkCharge-BE

Length of output: 2840


🏁 Script executed:

# Restaurant 엔티티 클래스 전체 내용 확인
cat -n src/main/java/konkuk/corkCharge/domain/restaurant/domain/Restaurant.java

Repository: CorkCharge/CorkCharge-BE

Length of output: 3844


🏁 Script executed:

# RestaurantRepository 전체 내용 확인
cat -n src/main/java/konkuk/corkCharge/domain/restaurant/repository/RestaurantRepository.java

Repository: CorkCharge/CorkCharge-BE

Length of output: 5265


🏁 Script executed:

# 데이터베이스 설정 확인
cat -n src/main/resources/application.yml

Repository: 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 쿼리를 통해 별도로 인덱스를 생성할 수 있습니다.

Comment on lines 30 to 32
/**LOCATION_REQUIRED
* 70000 : User
*/
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

주석 형식 오류를 수정해주세요.

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.

Suggested change
/**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.

@jaepar jaepar merged commit c13195f into develope Jan 8, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] [FEAT] 가까운 매장 조회 기능 개발

2 participants