Skip to content

[REFACTOR] 웨이블존 추천 경로 30km 이상 예외 처리#132

Merged
zyovn merged 3 commits into
developfrom
feature/jeongbin
Aug 12, 2025
Merged

[REFACTOR] 웨이블존 추천 경로 30km 이상 예외 처리#132
zyovn merged 3 commits into
developfrom
feature/jeongbin

Conversation

@zyovn

@zyovn zyovn commented Aug 12, 2025

Copy link
Copy Markdown
Member

✔️ 연관 이슈

📝 작업 내용

웨이블존 추천 경로 30km 이상 예외 처리

📸 스크린샷 (선택)

  • 강남 - 인천공항
스크린샷 2025-08-12 152141

Summary by CodeRabbit

  • 신규 기능

    • 경로가 최대 허용 거리(30km)를 초과할 경우 HTTP 400 오류와 안내 메시지를 반환합니다.
  • 개선

    • 경로 거리 계산을 폴리라인 기반으로 전환하여 총 거리 표시 정확도를 높였습니다.
    • 출발/도착 주변 약 1km 범위 내 노드만 탐색해 더 신뢰도 높은 경로를 제공합니다; 범위 외면 경로를 찾지 못할 수 있습니다.

@zyovn zyovn self-assigned this Aug 12, 2025
@zyovn zyovn added 🐛 bug fix 버그 수정 🛠️ fix 기능 오류 및 코드 개선이 필요한 곳 수정 labels Aug 12, 2025
@coderabbitai

coderabbitai Bot commented Aug 12, 2025

Copy link
Copy Markdown

Walkthrough

웨이블 경로 거리 상한(30km) 예외를 도입하고 폴리라인 기반 하버사인 합산으로 거리 계산을 변경했으며, 걷기 서비스의 최근접 노드 탐색에 1km 반경 필터를 추가하고 새로운 에러 케이스 DISTANCE_LIMIT_EXCEEDED를 정의했습니다.

Changes

Cohort / File(s) Summary
Error enums
src/main/java/com/wayble/server/direction/exception/WalkingErrorCase.java
새 에러 상수 DISTANCE_LIMIT_EXCEEDED(400, 8005) 추가
Walking node search radius
src/main/java/com/wayble/server/direction/service/WalkingService.java
NODE_SEARCH_RADIUS = 1000 도입, findNearestNode에 반경 필터 추가; 후보 없으면 NODE_NOT_FOUND 예외 발생
Dijkstra distance limit + polyline distance
src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java
MAX_DISTANCE = 30000.0 도입, 경로 거리 계산을 폴리라인 기반 하버사인 합산으로 변경, 30km 이상이면 ApplicationException(WalkingErrorCase.DISTANCE_LIMIT_EXCEEDED) 발생; 폴리라인 생성 흐름 정리 및 중복 제거

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant WaybleDijkstraService as DijkstraService
  participant Graph
  participant Util as HaversineUtil

  Client->>DijkstraService: requestPath(start, end)
  DijkstraService->>Graph: computePath(start, end)
  Graph-->>DijkstraService: path (nodes/edges)
  DijkstraService->>DijkstraService: polyline = createPolyLine(path)
  DijkstraService->>Util: calculateDistance(polyline)
  Util-->>DijkstraService: totalDistance
  alt totalDistance >= 30000
    DijkstraService-->>Client: throw ApplicationException(DISTANCE_LIMIT_EXCEEDED)
  else
    DijkstraService-->>Client: WayblePathResponse(distance from polyline, time from path)
  end
Loading
sequenceDiagram
  participant Client
  participant WalkingService
  participant Util as HaversineUtil
  participant Repo as NodeRepo

  Client->>WalkingService: findNearestNode(lat, lon)
  WalkingService->>Repo: loadCandidateNodes()
  loop filter within 1000m
    WalkingService->>Util: haversine(lat, lon, node.lat, node.lon)
  end
  alt candidates found
    WalkingService-->>Client: nearest node
  else
    WalkingService-->>Client: throw ApplicationException(NODE_NOT_FOUND)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
웨이블존 추천 경로 30km 이상 예외 처리 [#127]

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
최근접 노드 탐색에 1km 반경 필터 추가 (src/main/java/com/wayble/server/direction/service/WalkingService.java, method: findNearestNode) 이슈 #127은 30km 거리 초과 예외 처리만 명시하며, 노드 탐색 반경 제한은 해당 요구 사항에 포함되지 않습니다.

Possibly related PRs

Suggested reviewers

  • seung-in-Yoo
  • hyoinYang

Poem

"풀밭 위에서 길을 재는 토끼예요 🐇
폴리라인 따라 깡충깡충 한 걸음씩,
삼만 미터 넘으면 살짝 멈추고,
'너무 멀어' 속삭이며 길을 다시 그려요,
오늘도 안전한 길만 골라 달려요."

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/jeongbin

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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

@zyovn zyovn added 🔧 refactor 코드 리팩토링 and removed 🐛 bug fix 버그 수정 labels Aug 12, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (5)
src/main/java/com/wayble/server/direction/exception/WalkingErrorCase.java (1)

15-16: 에러 메시지 표현(“초과”)과 비즈니스 요건(“이상”) 불일치 — 문구 정합성 보완 권장

PR 목적이 “30km 이상”에 대한 예외 처리이므로, 메시지도 “이상”으로 맞추는 것이 혼선을 줄입니다. DirectionErrorCase에도 유사 문구(“이상”)가 있어 일관성 측면에서도 이득입니다.

다음과 같이 문구만 조정하면 됩니다:

-    DISTANCE_LIMIT_EXCEEDED(400, 8005, "경로가 허용 최대 거리(30km)를 초과하였습니다."),
+    DISTANCE_LIMIT_EXCEEDED(400, 8005, "경로가 허용 최대 거리(30km) 이상입니다."),
src/main/java/com/wayble/server/direction/service/WalkingService.java (2)

30-31: 상수의 단위 명시로 가독성 강화

반경이 미터 단위임을 상수명에 반영하면 오해를 줄일 수 있습니다.

아래처럼 상수명을 변경하고 주석으로 단위를 명시하는 것을 권장합니다:

-    private static final double NODE_SEARCH_RADIUS = 1000;
+    // meters
+    private static final double NODE_SEARCH_RADIUS_M = 1000;

참고: 아래 필터 사용부의 상수명도 함께 변경되어야 합니다(별도 코멘트에 제안).


55-63: 하버사인 반복 계산 제거(필터·정렬 중복 계산)로 미세 성능 개선

현재는 필터에서 한 번, min 비교에서 다시 한 번 거리를 계산합니다. 한 번만 계산해 재활용하세요.

다음과 같이 거리 값을 맵핑해 필터/정렬에서 재사용하는 방식이 간결합니다(위 제안한 상수명 변경도 반영):

-        return graphInit.getNodeMap().values().stream()
-                .filter(node -> HaversineUtil.haversine(lat, lon, node.lat(), node.lon()) <= NODE_SEARCH_RADIUS)
-                .min(Comparator.comparingDouble(
-                        node -> HaversineUtil.haversine(lat, lon, node.lat(), node.lon())
-                ))
-                .map(Node::id)
-                .orElseThrow(() -> new ApplicationException(WalkingErrorCase.NODE_NOT_FOUND));
+        return graphInit.getNodeMap().values().stream()
+                .map(node -> new java.util.AbstractMap.SimpleEntry<>(
+                        node, HaversineUtil.haversine(lat, lon, node.lat(), node.lon())))
+                .filter(e -> e.getValue() <= NODE_SEARCH_RADIUS_M)
+                .min(Comparator.comparingDouble(java.util.Map.Entry::getValue))
+                .map(e -> e.getKey().id())
+                .orElseThrow(() -> new ApplicationException(WalkingErrorCase.NODE_NOT_FOUND));
src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java (2)

24-24: 상수의 단위 명시로 의도 명확화

거리가 미터 단위임을 상수명에 반영하면 코드만 보고도 단위를 파악할 수 있습니다.

아래처럼 이름을 바꾸고(미터 표기), 비교 구문도 같이 수정하세요:

-    private static final double MAX_DISTANCE = 30000.0;
+    // meters
+    private static final double MAX_DISTANCE_M = 30000.0;

위 이름 변경 시, 사용처:

-        if (totalDistanceMeters >= MAX_DISTANCE) {
+        if (totalDistanceMeters >= MAX_DISTANCE_M) {

30-35: 에지 케이스 및 회귀 방지용 테스트를 추가하세요

  • 29,999.4m, 29,999.6m, 30,000.0m 케이스에 대해 각각 예외 미발생/발생 여부를 검증하는 단위 테스트가 필요합니다(반올림 이슈 회귀 방지).
  • 경로가 매우 짧거나(폴리라인 점 0~1개)인 경우 0m 반환/예외 없음도 확인하면 좋습니다.

원하시면 해당 시나리오에 대한 테스트 템플릿을 생성해 드리겠습니다.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03ed0a3 and 1361a68.

📒 Files selected for processing (3)
  • src/main/java/com/wayble/server/direction/exception/WalkingErrorCase.java (1 hunks)
  • src/main/java/com/wayble/server/direction/service/WalkingService.java (2 hunks)
  • src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/main/java/com/wayble/server/direction/exception/WalkingErrorCase.java (4)
src/main/java/com/wayble/server/direction/exception/DirectionErrorCase.java (1)
  • Getter (7-19)
src/main/java/com/wayble/server/wayblezone/exception/WaybleZoneErrorCase.java (1)
  • Getter (7-18)
src/main/java/com/wayble/server/direction/controller/WalkingController.java (3)
  • Override (22-34)
  • RestController (15-46)
  • Override (36-45)
src/main/java/com/wayble/server/direction/service/TransportationService.java (1)
  • PATH_NOT_FOUND (82-82)
src/main/java/com/wayble/server/direction/service/WalkingService.java (1)
src/main/java/com/wayble/server/direction/init/GraphInit.java (2)
  • n (86-86)
  • findWaybleMarkers (80-96)
src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java (2)
src/main/java/com/wayble/server/direction/service/util/HaversineUtil.java (1)
  • HaversineUtil (3-16)
src/main/java/com/wayble/server/direction/dto/response/WayblePathResponse.java (1)
  • Builder (9-49)
🔇 Additional comments (2)
src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java (2)

120-127: 폴리라인 기반 거리 합산 구현 적절

좌표가 [lon, lat] 순서로 저장되는 것을 감안해 Haversine 호출 시 (lat, lon) 순으로 역치환하는 부분이 정확합니다. 연속 좌표 간 누적 합산도 문제 없습니다.


10-10: 패키지 경로 일치 확인
HaversineUtil의 패키지 선언(com.wayble.server.direction.service.util)과 모든 import 경로가 일치하므로 수정이 필요하지 않습니다.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java (1)

30-37: 반올림 이전(double 원값)으로 임계값 비교 — 오탐 방지 방향으로 올바르게 수정됨

거리 비교를 반올림 전에 수행하도록 바뀌어 29,999.6m 같은 경계값에서의 오탐을 제거했습니다. 이전 리뷰 피드백이 잘 반영되었습니다.

🧹 Nitpick comments (2)
src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java (2)

24-24: MAX_DISTANCE 단위 명확화 및 설정값화 제안

상수의 단위를 이름에 드러내면 오해를 줄이고 유지보수성이 좋아집니다. 또한 환경별 상한 조정이 필요한 경우가 많으므로 설정값으로 외부화하는 것을 권장합니다.

  • 네이밍: MAX_DISTANCE_METERS
  • 설정값화: application.yml/properties로 이관하고 @value 또는 ConfigurationProperties로 주입

적용 예시(네이밍 변경):

-    private static final double MAX_DISTANCE = 30000.0;
+    private static final double MAX_DISTANCE_METERS = 30_000.0;

그리고 비교부:

-        if (totalDistanceMeters >= MAX_DISTANCE) {
+        if (totalDistanceMeters >= MAX_DISTANCE_METERS) {

121-129: 하버사인 입력(lat, lon) 순서 정확 — 가독성 소폭 개선 제안

[lon, lat] 형태의 polyline을 [lat, lon] 순서로 변환해 하버사인에 전달한 점은 정확합니다. 다만 인덱스 접근이 반복되어 가독성이 떨어지므로, 로컬 변수로 풀어 쓰는 것을 권장합니다. polyline 길이가 2 미만인 경우 빠른 반환도 추가하면 의도가 분명해집니다.

-    private double calculateDistance(List<double[]> polyline) {
-        double totalDistance = 0.0;
-
-        for (int i = 1; i <  polyline.size(); i++) {
-            totalDistance += HaversineUtil.haversine(
-                    polyline.get(i - 1)[1], polyline.get(i - 1)[0],
-                    polyline.get(i)[1],     polyline.get(i)[0]
-            );
-        }
-        return totalDistance;
-    }
+    private double calculateDistance(List<double[]> polyline) {
+        if (polyline.size() < 2) return 0.0;
+        double totalDistance = 0.0;
+        for (int i = 1; i < polyline.size(); i++) {
+            double prevLon = polyline.get(i - 1)[0], prevLat = polyline.get(i - 1)[1];
+            double currLon = polyline.get(i)[0],     currLat = polyline.get(i)[1];
+            totalDistance += HaversineUtil.haversine(prevLat, prevLon, currLat, currLon);
+        }
+        return totalDistance;
+    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1361a68 and 42b18ff.

📒 Files selected for processing (1)
  • src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java (2)
src/main/java/com/wayble/server/direction/service/util/HaversineUtil.java (1)
  • HaversineUtil (3-16)
src/main/java/com/wayble/server/direction/dto/response/WayblePathResponse.java (1)
  • Builder (9-49)
🔇 Additional comments (1)
src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java (1)

3-11: 필요한 예외/유틸 import 추가 적절

DISTANCE_LIMIT 예외 처리와 하버사인 거리계산 도입에 따른 import 추가가 정확합니다.

@zyovn zyovn merged commit d67da3f into develop Aug 12, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠️ fix 기능 오류 및 코드 개선이 필요한 곳 수정 🔧 refactor 코드 리팩토링

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant