Skip to content

Conversation

@hyoinYang
Copy link
Contributor

@hyoinYang hyoinYang commented Aug 15, 2025

✔️ 연관 이슈

📝 작업 내용

현재까지의 진행상황을 main으로 머지

스크린샷 (선택)

Summary by CodeRabbit

  • 신기능
    • Wayble Zone 상세에 이전/다음 이동 버튼 추가.
    • 경로 결과에 보행 구간의 실제 이동 거리 표시.
    • 경로 컨텍스트를 반영한 노선별 휠체어 위치 정보 노출.
  • 버그 수정
    • 대중교통 정보 조회 안정성 개선(타임아웃/재시도, 오류 시 기본값 처리).
    • 역 화장실 접근성 정보 처리의 누락/중복 방지 및 신뢰성 향상.
  • 잡무
    • 보행 그래프와 마커 데이터 대폭 보강 및 분류 정정.
    • 환승 제한 기준 조정으로 더 간결한 추천 경로 제공.

zyovn and others added 20 commits August 12, 2025 17:54
[feat] 공덕 지역 웨이블존 데이터 추가
[FEAT] 공덕 지역 웨이블 마커 데이터 추가
[FIX] kric api의 안정성 강화, 환승 횟수 로직 정교화 및 횟수 제한 강화
@hyoinYang hyoinYang self-assigned this Aug 15, 2025
@hyoinYang hyoinYang added the release 프로덕션 서버에 배포 label Aug 15, 2025
@coderabbitai
Copy link

coderabbitai bot commented Aug 15, 2025

Walkthrough

관리자 WaybleZone 상세에 이전/다음 내비게이션을 추가하고, 이에 필요한 DTO/서비스/레포지토리를 도입했습니다. 교통 도메인에서는 DTO 시그니처 변경, 휠체어/엘리베이터 정보 처리 방식 개편, KRIC 화장실 API 연계 수정, 경로 필터·이동거리·환승 계산 로직을 조정했습니다. 그래프/마커 리소스와 일부 설정·테스트도 갱신했습니다.

Changes

Cohort / File(s) Summary
Admin WaybleZone 내비게이션
src/main/java/.../admin/controller/wayblezone/AdminWaybleZoneViewController.java, src/main/java/.../admin/dto/wayblezone/AdminWaybleZoneNavigationDto.java, src/main/java/.../admin/repository/AdminWaybleZoneRepositoryCustom.java, src/main/java/.../admin/repository/AdminWaybleZoneRepositoryImpl.java, src/main/java/.../admin/service/AdminWaybleZoneService.java, src/main/resources/templates/admin/wayblezone/wayble-zone-detail.html
상세 페이지에 이전/다음 이동 정보 제공. Navigation DTO 추가, 레포지토리 커스텀 메서드/구현 추가(getNavigationInfo), 서비스 위임 메서드 추가, 컨트롤러에서 모델에 navigation 주입, 템플릿에 이전/다음 버튼 조건 렌더링.
교통 DTO/서비스 및 시설 연계
src/main/java/.../direction/dto/response/TransportationResponseDto.java, src/main/java/.../direction/service/FacilityService.java, src/main/java/.../direction/service/TransportationService.java, src/main/java/.../direction/repository/FacilityRepository.java, src/main/java/.../direction/entity/transportation/Facility.java, src/main/java/.../direction/entity/transportation/Route.java, src/main/java/.../direction/entity/transportation/Wheelchair.java, src/main/java/.../direction/repository/WheelchairInfoRepository.java
Response DTO 변경(Step에 to 추가, Subway/NodeInfo의 wheelchair/elevator를 List로 변경). FacilityService#getNodeInfo(Long, Long)로 시그니처 확장 및 휠체어 위치를 Route 기준으로 조회, KRIC 화장실 정보 처리 로직/엔드포인트 갱신. TransportationService에서 최대 환승 기준 변경, WALK 실제 거리 계산, 예외/기본값 처리 개선, getNodeInfo 호출에 routeId 전달. Facility id의 자동 생성 제거, Route에 Wheelchair 일대다 추가, Wheelchair 엔티티/레포지토리 추가, FacilityRepository는 JPQL로 fetch join 도입.
KRIC 연동 및 WebClient 설정
src/main/java/.../common/config/WebClientConfig.java, src/main/java/.../direction/external/kric/dto/KricToiletRawItem.java, src/main/java/.../direction/external/kric/dto/KricToiletRawResponse.java, src/main/java/.../direction/external/kric/dto/KricToiletRawBody.java
KRIC WebClient에 2MB in-memory limit, 타임아웃(15s)과 재시도(예외별 최대 3회) 필터 추가. KRIC DTO 재정의: RawItem 필드/순서 확장, RawResponse가 body를 List으로 보유하도록 변경, RawBody 레코드 제거.
그래프/마커 데이터
src/main/java/.../direction/init/GraphInit.java, src/main/resources/wayble_markers.json
그래프 초기화 리소스를 seocho_gongdeok_pedestrian.json으로 교체. 마커 JSON에 대량 추가 및 유형 재분류(RAMP→WHEELCHAIR_* 또는 NONE 등).
기타 정리
src/main/java/.../wayblezone/importer/CsvSupport.java, src/test/java/.../direction/service/WalkingServiceTest.java
CsvSupport에 Slf4j import 추가(미사용). 테스트에서 불필요한 공백 제거.

Sequence Diagram(s)

sequenceDiagram
  participant Admin as Admin UI
  participant Ctrl as AdminWaybleZoneViewController
  participant Svc as AdminWaybleZoneService
  participant Repo as AdminWaybleZoneRepository

  Admin->>Ctrl: GET /admin/wayble-zones/{id}
  Ctrl->>Svc: getNavigationInfo(id)
  Svc->>Repo: getNavigationInfo(id)
  Repo-->>Svc: AdminWaybleZoneNavigationDto(prevId,nextId)
  Svc-->>Ctrl: Navigation DTO
  Ctrl-->>Admin: View(Model: navigation, details)
Loading
sequenceDiagram
  participant TS as TransportationService
  participant FS as FacilityService
  participant NR as NodeRepository
  participant FR as FacilityRepository
  participant WC as WheelchairInfoRepository
  participant KRIC as KRIC API

  TS->>FS: getNodeInfo(nodeId, routeId)
  FS->>NR: findById(nodeId)
  NR-->>FS: Node
  FS->>WC: findByRouteId(routeId)
  WC-->>FS: List<Wheelchair>
  FS->>FR: findByNodeId(nodeId) (fetch lifts)
  FR-->>FS: Facility
  FS->>KRIC: stationDisabledToilet(... identifiers ...)
  KRIC-->>FS: List<KricToiletRawItem>
  FS-->>TS: NodeInfo(wheelchair locations, elevator=[], restroom flag)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

🛠️ fix

Suggested reviewers

  • zyovn
  • seung-in-Yoo

Poem

토끼는 귀를 쫑긋, 길을 잇는 선을 본다
이전, 다음 살짝 점프—존을 건너뛰고
바퀴 흔적 따라 반짝, 휠체어 길을 적고
화장실 표식은 별처럼 지도 위에
“띠딩!” 그래프가 깨어난다—hop, hop, 출발! 🐇✨

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 Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch develop

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.

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

🔭 Outside diff range comments (3)
src/main/java/com/wayble/server/direction/init/GraphInit.java (3)

60-62: RAMP 패널티가 절대 적용되지 않는 버그(rampMarkers 초기화 누락)

rampMarkers가 항상 emptySet이어서(초기값만 존재) RAMP_PENALTY가 절대 적용되지 않습니다. markerMap 계산 직후, RAMP 타입 노드를 rampMarkers에 채워 넣어야 합니다.

-            markerMap = findWaybleMarkers();
-            adjacencyList = buildAdjacencyList();
+            markerMap = findWaybleMarkers();
+            // RAMP 타입 노드를 별도로 모아 패널티 적용
+            rampMarkers = markerMap.entrySet().stream()
+                    .filter(e -> e.getValue() == Type.RAMP)
+                    .map(Map.Entry::getKey)
+                    .collect(Collectors.toSet());
+            adjacencyList = buildAdjacencyList();

71-79: NONE 타입에도 할인 적용되는 로직 오류(타입별 가중치 적용 필요)

현 로직은 “마커가 있다”는 이유만으로 MARKER_DISCOUNT를 적용합니다. Type.NONE까지 할인되는 것은 비즈니스 의도와 어긋날 가능성이 큽니다. 타입별로 패널티/할인을 분기하세요.

-        for (Edge edge : edges) {
-            boolean isWaybleMarker = markerMap.containsKey(edge.from()) || markerMap.containsKey(edge.to());
-            boolean isRamp = rampMarkers.contains(edge.from()) || rampMarkers.contains(edge.to());
-
-            double distance = edge.length();
-
-            if (isRamp) distance *= RAMP_PENALTY;
-            else if (isWaybleMarker) distance *= MARKER_DISCOUNT;
+        for (Edge edge : edges) {
+            final Type fromType = markerMap.get(edge.from());
+            final Type toType   = markerMap.get(edge.to());
+
+            double distance = edge.length();
+
+            // RAMP는 패널티, 엘리베이터/리프트/충전기는 할인, NONE은 조정 없음
+            if (fromType == Type.RAMP || toType == Type.RAMP) {
+                distance *= RAMP_PENALTY;
+            } else if (isPositiveMarker(fromType) || isPositiveMarker(toType)) {
+                distance *= MARKER_DISCOUNT;
+            }

추가 헬퍼 메서드(클래스 내부 어떤 위치든 무방):

private boolean isPositiveMarker(Type t) {
    if (t == null) return false;
    return t == Type.WHEELCHAIR_LIFT
        || t == Type.WHEELCHAIR_CHARGER
        // 필요 시 다른 “편의” 타입도 추가
        || t == Type.ELEVATOR;
}

92-103: 가까운 노드 매핑 조건 오류: marker.id()와 node.id() 비교는 의미가 없습니다

현재 로직은 “가까운 노드 ID(nearNode)가 marker.id()와 동일하면 매핑을 생략”합니다. 노드 ID와 마커 ID는 서로 다른 도메인이라 일반적으로 일치하지 않으며, 해당 조건은 사실상 임의의 생략을 유발합니다. 최근접 노드에 항상 매핑하도록 수정하세요.

-            if (nearNode != marker.id()) {
-                waybleMarkers.put(nearNode, marker.type());
-            }
+            waybleMarkers.put(nearNode, marker.type());

추가 개선(선택): 임계 거리(예: 100m)를 두고, 초과 시 매핑을 생략하면 그래프 외곽/원거리 마커의 오매핑을 방지할 수 있습니다. 원하시면 해당 로직까지 포함해 패치 드리겠습니다.

🧹 Nitpick comments (13)
src/main/resources/wayble_markers.json (1)

1-7874: 데이터 볼륨 급증에 따른 초기화 성능/정확도 리스크

  • 성능: 현재 GraphInit.findWaybleMarkers는 O(N_nodes × N_markers)입니다. 수천~수만 단위에서 초기화 시간이 커질 수 있습니다.
  • 정확도: 그래프 적용 범위를 넘어서는 원거리 마커도 “가장 가까운 노드”로 맵핑됩니다(거리 임계치 없이). 이 경우 특정 노드/엣지에 부적절한 할인/패널티가 적용될 수 있습니다.

완화 제안:

  • 공간 인덱스 도입(KD-Tree, R*-tree, 혹은 geohash 그리드 버킷)으로 최근접 탐색을 가속.
  • 맵핑 거리 임계치(e.g. 100m)를 두고, 기준 초과 시 매핑 생략.

원하시면 HaversineUtil 기반의 그리드 버킷 샘플 구현을 드리겠습니다.

src/main/java/com/wayble/server/direction/init/GraphInit.java (2)

56-58: ObjectMapper TypeReference 제네릭 명시(가독성/타입 안전성 개선)

다이아몬드 연산자 + 익명 클래스 조합은 컴파일러 버전/옵션에 따라 가독성과 경고 면에서 불리할 수 있습니다. 제네릭을 명시해 주세요.

-                markers = markerStream != null
-                        ? objectMapper.readValue(markerStream, new TypeReference<>() {})
-                        : new ArrayList<>();
+                markers = markerStream != null
+                        ? objectMapper.readValue(markerStream, new TypeReference<List<WaybleMarker>>() {})
+                        : new ArrayList<>();

92-99: 초기화 성능 최적화 제안: 최근접 탐색 가속화

모든 마커마다 모든 노드를 순회하는 O(N×M)은 데이터가 커질수록 초기화 지연을 유발합니다. KD-Tree/Grid bucketing 등으로 근방 노드 후보군만 비교하도록 개선하세요.

원하시면 geohash 버킷 기반 근접 후보 탐색 샘플을 제공하겠습니다(외부 라이브러리 없이도 구현 가능).

src/main/java/com/wayble/server/admin/repository/AdminWaybleZoneRepositoryCustom.java (1)

18-19: 이전/다음 조회 API 추가 적절 — null 의미를 인터페이스 수준에서 명시하면 더 좋습니다

반환 DTO의 previousId/nextId가 없을 때 null임을 Javadoc으로 명시하면, 서비스/컨트롤러/템플릿에서의 처리 기준이 더 명확해집니다. 예: “가장 작은/가장 큰 ID 경계에서는 해당 값이 null”.

src/main/java/com/wayble/server/common/config/WebClientConfig.java (2)

35-38: timeout은 재시도 대상이 아닙니다 + 비멱등 메서드까지 재시도됩니다

현재 .timeout(...).retryWhen(... .filter(WebClientRequestException)) 구성이라, TimeoutException은 재시도되지 않습니다. 또한 HTTP 메서드에 상관없이 재시도되어 POST/PUT 같은 비멱등 요청에도 적용될 수 있습니다.

다음과 같이 개선을 제안합니다: (1) GET/HEAD 등 멱등 메서드에 한해 재시도, (2) TimeoutException도 재시도 대상으로 포함.

-                .filter((request, next) -> next.exchange(request)
-                        .timeout(java.time.Duration.ofSeconds(15))
-                        .retryWhen(reactor.util.retry.Retry.backoff(3, java.time.Duration.ofSeconds(1))
-                                .filter(throwable -> throwable instanceof org.springframework.web.reactive.function.client.WebClientRequestException)))
+                .filter((request, next) -> {
+                    boolean retryableMethod = request.method() == org.springframework.http.HttpMethod.GET
+                            || request.method() == org.springframework.http.HttpMethod.HEAD;
+                    var exchange = next.exchange(request)
+                            .timeout(java.time.Duration.ofSeconds(15));
+                    if (!retryableMethod) {
+                        return exchange;
+                    }
+                    return exchange.retryWhen(
+                            reactor.util.retry.Retry.backoff(3, java.time.Duration.ofSeconds(1))
+                                    .filter(t -> t instanceof org.springframework.web.reactive.function.client.WebClientRequestException
+                                            || t instanceof java.util.concurrent.TimeoutException)
+                    );
+                })

추가로, 재시도 로그를 남기려면 Retry.backoff(...).doBeforeRetry(rs -> log.warn(...))를 덧붙이는 것도 권장합니다.


34-34: maxInMemorySize 2MB 하드코딩 → 프로퍼티화 제안

KRIC 응답 크기가 변동 가능하다면, 2MB는 환경에 따라 부족할 수 있습니다. application.yml에 예: wayble.kric.max-in-memory-size 프로퍼티를 두고 주입받아 설정하도록 하면 운영/스테이지별 튜닝이 용이합니다.

src/main/java/com/wayble/server/direction/repository/FacilityRepository.java (1)

13-16: 메서드명(findByNodeId)과 JPQL 조건(f.id) 불일치

Facility@MapsIdnode.id와 동일하다면 기능상 문제는 없겠지만, 가독성 측면에서 혼동을 유발합니다. 실제 의도가 Node의 id 기준 조회라면 JPQL도 f.node.id로 맞추거나, 메서드명을 findByIdWithLifts로 바꾸는 것을 권장합니다.

아래와 같이 대안도 고려 가능합니다.

-    @Query("SELECT DISTINCT f FROM Facility f " +
-           "LEFT JOIN FETCH f.lifts " +
-           "WHERE f.id = :nodeId")
+    @Query("SELECT DISTINCT f FROM Facility f " +
+           "LEFT JOIN FETCH f.lifts " +
+           "WHERE f.node.id = :nodeId")
     Optional<Facility> findByNodeId(@Param("nodeId") Long nodeId);
src/main/java/com/wayble/server/direction/dto/response/TransportationResponseDto.java (2)

23-23: moveNumber의 이중 의미(횟수 vs 거리)로 인한 클라이언트 혼동 가능성

WALK에서는 거리(m), 그 외에는 이동 횟수로 쓰이면, 소비 측에서 단위/의미 분기가 필요합니다. 필드를 분리(moveCount, distanceMeters)하거나, 최소한 스키마 설명에 단위를 명시하고 예시를 추가해 주세요.


58-61: NodeInfo의 필드 타입 변경도 동일한 호환성 이슈

NodeInfo.wheelchair/elevator 역시 List로 변경. 동일한 백워드 컴패티빌리티 전략과 문서 갱신이 필요합니다.

src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawItem.java (1)

6-17: KRIC 응답 필드명 매핑 검증 필요 + Lombok import 불필요

  • 현재 Record 필드명이 KRIC JSON/XML 필드명과 1:1 매칭되어야 역직렬화가 성공합니다. 외부 API가 snake_case, 대소문자/축약이 다르면 @JsonProperty 명시를 권장합니다.
  • 이 파일에서는 lombok.Getter가 사용되지 않습니다(Record는 자동 접근자 생성). 불필요한 import는 제거 바랍니다.

예시:

public record KricToiletRawItem(
    @com.fasterxml.jackson.annotation.JsonProperty("railOprIsttCd") String railOprIsttCd,
    @com.fasterxml.jackson.annotation.JsonProperty("lnCd") String lnCd,
    // ...
) {}
src/main/java/com/wayble/server/direction/entity/transportation/Route.java (1)

38-41: 양방향 관계의 일관성 관리 필요

RouteWheelchair 간의 양방향 관계가 설정되었지만, 관계의 일관성을 보장하는 헬퍼 메서드가 없습니다. 휠체어 정보를 추가/제거할 때 양방향 관계가 올바르게 유지되도록 메서드를 추가하는 것을 고려해보세요.

 @OneToMany(mappedBy = "route", fetch = FetchType.LAZY)
 private List<Wheelchair> wheelchairs;
+
+// 양방향 관계 관리를 위한 헬퍼 메서드
+public void addWheelchair(Wheelchair wheelchair) {
+    if (wheelchairs == null) {
+        wheelchairs = new ArrayList<>();
+    }
+    wheelchairs.add(wheelchair);
+    wheelchair.setRoute(this);
+}
+
+public void removeWheelchair(Wheelchair wheelchair) {
+    if (wheelchairs != null) {
+        wheelchairs.remove(wheelchair);
+        wheelchair.setRoute(null);
+    }
+}
src/main/java/com/wayble/server/direction/repository/WheelchairInfoRepository.java (1)

9-10: 사용되지 않는 import 제거

Optional import가 선언되어 있지만 실제로 사용되지 않습니다.

 import java.util.List;
-import java.util.Optional;
src/main/java/com/wayble/server/direction/entity/transportation/Wheelchair.java (1)

8-8: Builder 접근 레벨 제한 필요

다른 엔티티들과 일관성을 유지하기 위해 @BuilderAccessLevel.PRIVATE을 추가하는 것이 좋습니다.

-@Builder
+@Builder(access = AccessLevel.PRIVATE)
📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between f297e27 and cfbf03f.

⛔ Files ignored due to path filters (1)
  • src/main/resources/data/gongduck_wayblezone.csv is excluded by !**/*.csv
📒 Files selected for processing (22)
  • src/main/java/com/wayble/server/admin/controller/wayblezone/AdminWaybleZoneViewController.java (2 hunks)
  • src/main/java/com/wayble/server/admin/dto/wayblezone/AdminWaybleZoneNavigationDto.java (1 hunks)
  • src/main/java/com/wayble/server/admin/repository/AdminWaybleZoneRepositoryCustom.java (2 hunks)
  • src/main/java/com/wayble/server/admin/repository/AdminWaybleZoneRepositoryImpl.java (2 hunks)
  • src/main/java/com/wayble/server/admin/service/AdminWaybleZoneService.java (2 hunks)
  • src/main/java/com/wayble/server/common/config/WebClientConfig.java (1 hunks)
  • src/main/java/com/wayble/server/direction/dto/response/TransportationResponseDto.java (3 hunks)
  • src/main/java/com/wayble/server/direction/entity/transportation/Facility.java (0 hunks)
  • src/main/java/com/wayble/server/direction/entity/transportation/Route.java (2 hunks)
  • src/main/java/com/wayble/server/direction/entity/transportation/Wheelchair.java (1 hunks)
  • src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawBody.java (0 hunks)
  • src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawItem.java (1 hunks)
  • src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawResponse.java (1 hunks)
  • src/main/java/com/wayble/server/direction/init/GraphInit.java (1 hunks)
  • src/main/java/com/wayble/server/direction/repository/FacilityRepository.java (1 hunks)
  • src/main/java/com/wayble/server/direction/repository/WheelchairInfoRepository.java (1 hunks)
  • src/main/java/com/wayble/server/direction/service/FacilityService.java (4 hunks)
  • src/main/java/com/wayble/server/direction/service/TransportationService.java (5 hunks)
  • src/main/java/com/wayble/server/wayblezone/importer/CsvSupport.java (1 hunks)
  • src/main/resources/templates/admin/wayblezone/wayble-zone-detail.html (1 hunks)
  • src/main/resources/wayble_markers.json (4 hunks)
  • src/test/java/com/wayble/server/direction/service/WalkingServiceTest.java (0 hunks)
💤 Files with no reviewable changes (3)
  • src/test/java/com/wayble/server/direction/service/WalkingServiceTest.java
  • src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawBody.java
  • src/main/java/com/wayble/server/direction/entity/transportation/Facility.java
🧰 Additional context used
🧬 Code Graph Analysis (14)
src/main/java/com/wayble/server/admin/dto/wayblezone/AdminWaybleZoneNavigationDto.java (2)
src/main/java/com/wayble/server/admin/dto/wayblezone/AdminWaybleZoneDetailDto.java (2)
  • AdminWaybleZoneDetailDto (10-59)
  • FacilityInfo (40-43)
src/main/java/com/wayble/server/admin/dto/wayblezone/AdminWaybleZonePageDto.java (1)
  • AdminWaybleZonePageDto (5-34)
src/main/java/com/wayble/server/direction/init/GraphInit.java (2)
src/test/java/com/wayble/server/direction/service/WalkingServiceTest.java (1)
  • BeforeEach (35-77)
src/main/java/com/wayble/server/direction/dto/TransportationGraphDto.java (1)
  • TransportationGraphDto (9-12)
src/main/java/com/wayble/server/admin/repository/AdminWaybleZoneRepositoryImpl.java (1)
src/main/java/com/wayble/server/admin/repository/AdminWaybleZoneRepository.java (1)
  • AdminWaybleZoneRepository (6-7)
src/main/java/com/wayble/server/wayblezone/importer/CsvSupport.java (3)
src/main/java/com/wayble/server/wayblezone/importer/SeochoCsvImporter.java (1)
  • Slf4j (31-172)
src/main/java/com/wayble/server/wayblezone/sync/WaybleZoneSyncScheduler.java (1)
  • Slf4j (8-35)
src/main/java/com/wayble/server/direction/service/DirectionService.java (1)
  • Slf4j (25-68)
src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawResponse.java (1)
src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawBody.java (1)
  • KricToiletRawBody (5-7)
src/main/java/com/wayble/server/direction/repository/WheelchairInfoRepository.java (2)
src/main/java/com/wayble/server/direction/repository/RouteRepository.java (1)
  • RouteRepository (7-9)
src/main/java/com/wayble/server/direction/repository/EdgeRepository.java (1)
  • Repository (10-17)
src/main/java/com/wayble/server/direction/entity/transportation/Wheelchair.java (1)
src/main/java/com/wayble/server/direction/entity/transportation/Route.java (1)
  • Entity (11-42)
src/main/java/com/wayble/server/direction/entity/transportation/Route.java (1)
src/main/java/com/wayble/server/direction/entity/transportation/Edge.java (1)
  • Entity (8-47)
src/main/resources/wayble_markers.json (1)
src/main/java/com/wayble/server/direction/entity/WaybleMarker.java (1)
  • WaybleMarker (5-11)
src/main/java/com/wayble/server/direction/repository/FacilityRepository.java (2)
src/main/java/com/wayble/server/direction/entity/transportation/Facility.java (1)
  • Entity (11-46)
src/main/java/com/wayble/server/direction/entity/transportation/Lift.java (1)
  • Entity (6-29)
src/main/java/com/wayble/server/direction/dto/response/TransportationResponseDto.java (1)
src/main/java/com/wayble/server/direction/dto/request/TransportationRequestDto.java (1)
  • Schema (5-17)
src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawItem.java (1)
src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawBody.java (1)
  • KricToiletRawBody (5-7)
src/main/java/com/wayble/server/direction/service/FacilityService.java (3)
src/main/java/com/wayble/server/direction/entity/transportation/Facility.java (1)
  • Entity (11-46)
src/main/java/com/wayble/server/direction/entity/transportation/Lift.java (1)
  • Entity (6-29)
src/main/java/com/wayble/server/direction/entity/transportation/Node.java (1)
  • Entity (13-79)
src/main/java/com/wayble/server/direction/service/TransportationService.java (1)
src/main/java/com/wayble/server/direction/service/WalkingService.java (1)
  • Slf4j (20-64)
🔇 Additional comments (22)
src/main/resources/wayble_markers.json (2)

1995-2005: 마커 타입 재분류(예: RAMP → WHEELCHAIR_LIFT/NONE 등) 영향 검증 필요

다음 라인 근처에서 타입 재분류가 보입니다. 경로 가중치 로직(특히 GraphInit의 마커 할인/패널티)에 직접적인 영향이 있습니다. 의도된 변경인지, 데이터 소스 기준과 합치하는지 확인 부탁드립니다.

  • Line 1998: id 1740825183 → type WHEELCHAIR_LIFT
  • Line 2004: id 1012654209 → type WHEELCHAIR_CHARGER
  • Line 2034: id 6875654572 → type NONE
  • Line 2154: id 2747865798 → type NONE

변경 이력/출처 기준 문서(또는 원천 데이터 변경 로그)가 있다면 레퍼런스와 함께 코멘트로 공유해 주세요. 필요 시 cross-check를 자동화하는 스크립트도 제공하겠습니다.

Also applies to: 2031-2035, 2152-2155


2-7: 검증 완료 — Type enum과 wayble_markers.json의 타입/ID/좌표가 일치합니다

스크립트 실행 결과 아래 항목들 모두 정상 확인되었습니다.

  • Type enum 파일: src/main/java/com/wayble/server/direction/entity/type/Type.java
    • 포함된 상수: WHEELCHAIR_CHARGER, NO_THRESHOLD, RAMP, WHEELCHAIR_LIFT, NONE
  • JSON 파일: src/main/resources/wayble_markers.json
    • 고유 타입 목록: NONE, RAMP, WHEELCHAIR_CHARGER, WHEELCHAIR_LIFT (모두 enum에 존재)
  • ID 중복: 없음
  • 위/경도 범위: 정상
  • 전체 마커 수: 1312

따라서 원래 지적한 역직렬화/스키마 불일치 우려는 해소되었습니다.

src/main/java/com/wayble/server/direction/init/GraphInit.java (2)

55-61: 검증 완료 — Type enum에 ELEVATOR와 WHEELCHAIR_LIFT가 모두 존재합니다

제공하신 스크립트 출력에서 src/main/java/com/wayble/server/direction/entity/type/Type.java에 ELEVATOR와 WHEELCHAIR_LIFT 상수가 모두 포함됨을 확인했습니다. 따라서 해당 변경으로 인한 역직렬화 실패나 가중치 분기 누락 우려는 없습니다.


43-52: 그래프 리소스 파일 존재 확인 — 문제 없음

  • 코드: src/main/java/com/wayble/server/direction/init/GraphInit.java — getResourceAsStream("/seocho_gongdeok_pedestrian.json")
  • 리소스: src/main/resources/seocho_gongdeok_pedestrian.json — 존재 확인됨

검증 완료.

src/main/java/com/wayble/server/wayblezone/importer/CsvSupport.java (1)

5-5: Slf4j import 추가는 일관성 측면에서 문제 없습니다

해당 클래스에서 로깅을 아직 사용하지 않더라도, 프로젝트 전반의 패턴(다른 Importer/Scheduler 등에서 @slf4j 사용)과의 일관성 관점에서는 무해합니다. 추후 CSV 파싱 실패나 카테고리 매핑 미스(Log at debug/info) 등에 활용하실 계획이라면 유지해도 좋습니다.

src/main/java/com/wayble/server/admin/dto/wayblezone/AdminWaybleZoneNavigationDto.java (1)

3-6: 간결하고 목적에 맞는 DTO 도입 👍

이전/다음 경계를 null로 표현하는 설계가 사용처(뷰에서의 조건부 렌더링)와 잘 맞습니다. 추후 필드가 늘어나지 않는 한 record 유지가 적절해 보입니다.

src/main/java/com/wayble/server/admin/service/AdminWaybleZoneService.java (1)

63-65: 단순 위임 메서드로 충분합니다

클래스 레벨 @transactional(readOnly = true) 컨텍스트와도 일치하고, 서비스 레이어 책임(Repository 캡슐화)을 충실히 수행합니다.

src/main/java/com/wayble/server/admin/repository/AdminWaybleZoneRepositoryImpl.java (1)

107-124: 확인 — WaybleZone 엔티티에 soft-delete 설정이 적용되어 있습니다

간단히 확인했습니다: src/main/java/com/wayble/server/wayblezone/entity/WaybleZone.java에
@SQLDelete(sql = "UPDATE wayble_zone SET deleted_at = now() WHERE id = ?")
및 @SQLRestriction("deleted_at IS NULL")가 선언되어 있어 soft-deleted 레코드는 기본적으로 제외됩니다. 따라서 현재 getNavigationInfo의 max/min 쿼리는 soft-deleted 레코드를 포함하지 않습니다.

수정이 필요한 위치

  • src/main/java/com/wayble/server/wayblezone/entity/WaybleZone.java — @SQLDelete, @SQLRestriction (클래스 선언부, 약 23–24행)

선택적 리팩터(성능): 집계(max/min) 대신 정렬+limit 방식 고려 가능(필수 아님):

  • 변경 전
    Long previousId = queryFactory
    .select(waybleZone.id.max())
    .from(waybleZone)
    .where(waybleZone.id.lt(currentId))
    .fetchOne();

    Long nextId = queryFactory
    .select(waybleZone.id.min())
    .from(waybleZone)
    .where(waybleZone.id.gt(currentId))
    .fetchOne();

  • 변경 후 (선택)
    Long previousId = queryFactory
    .select(waybleZone.id)
    .from(waybleZone)
    .where(waybleZone.id.lt(currentId))
    .orderBy(waybleZone.id.desc())
    .limit(1)
    .fetchOne();

    Long nextId = queryFactory
    .select(waybleZone.id)
    .from(waybleZone)
    .where(waybleZone.id.gt(currentId))
    .orderBy(waybleZone.id.asc())
    .limit(1)
    .fetchOne();

src/main/resources/templates/admin/wayblezone/wayble-zone-detail.html (1)

75-111: 네비게이션 UI 구현이 적절하게 구성되었습니다.

이전/다음 버튼의 조건부 렌더링과 비활성화 상태 처리가 올바르게 구현되어 있고, Tailwind CSS 스타일링과 접근성 고려도 적절합니다.

src/main/java/com/wayble/server/admin/controller/wayblezone/AdminWaybleZoneViewController.java (4)

5-5: 새로운 DTO import가 추가되었습니다.

네비게이션 기능을 위한 AdminWaybleZoneNavigationDto import가 적절하게 추가되었습니다.


62-67: 네비게이션 정보를 모델에 추가하는 로직이 적절합니다.

서비스에서 네비게이션 정보를 조회하여 모델에 추가하는 구현이 명확하고 올바릅니다.


69-69: 로깅 메시지에 네비게이션 정보가 포함되었습니다.

디버깅을 위한 로깅에 이전/다음 ID 정보가 포함되어 적절합니다.


62-69: 검증 완료 — 네비게이션 서비스 연동 정상 확인됨

요약: AdminWaybleZoneNavigationDto, Service의 getNavigationInfo 호출, Repository 인터페이스 선언 및 RepositoryImpl의 getNavigationInfo 구현이 모두 존재하고 일치합니다. 추가 수정은 필요하지 않습니다.

검증된 파일:

  • src/main/java/com/wayble/server/admin/dto/wayblezone/AdminWaybleZoneNavigationDto.java
  • src/main/java/com/wayble/server/admin/service/AdminWaybleZoneService.java (getNavigationInfo)
  • src/main/java/com/wayble/server/admin/repository/AdminWaybleZoneRepositoryImpl.java (getNavigationInfo 구현)
  • src/main/java/com/wayble/server/admin/repository/AdminWaybleZoneRepositoryCustom.java (메서드 선언)
  • src/main/java/com/wayble/server/admin/controller/wayblezone/AdminWaybleZoneViewController.java (컨트롤러 바인딩/로그)
src/main/java/com/wayble/server/direction/dto/response/TransportationResponseDto.java (1)

46-49: 타입 변경: List → List는 API 호환성에 영향

SubwayInfo.wheelchair/elevator가 문자열 리스트로 변경되었습니다. 기존 소비자(앱/프론트)가 좌표(lat/lng)를 기대했다면 즉시 깨집니다. 문서/스키마와 통합 테스트, 클라이언트 업데이트가 동반되어야 합니다.

  • OpenAPI 스키마 업데이트 여부 확인
  • 기존 필드를 한동안 유지(deprecate)하는 점진 이행 전략 고려
  • 서버 내부 변환 계층에서 과거 스키마로도 응답 가능한 백워드 컴패티빌리티 옵션 검토
src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawResponse.java (1)

6-6: 검증 요약: DTO 변경은 코드베이스에 반영되었으나 외부 KRIC 응답 스키마 확인 필요

KricToiletRawResponse의 bodyList<KricToiletRawItem>로 정의되어 있고, 서비스 호출부(FacilityService)도 해당 형태로 사용 중입니다. getBody().getItem() 같은 구식 접근이나 KricToiletRawBody 클래스 잔존은 확인되지 않았습니다. 다만 실제 KRIC API 응답이 여전히 body→item 같은 중첩 래퍼 구조라면 역직렬화가 실패하므로 API 응답 스키마(또는 통합 호출 테스트)를 반드시 검증해 주세요.

점검된 위치:

  • src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawResponse.java — body: List
  • src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawItem.java — item 레코드 정의
  • src/main/java/com/wayble/server/direction/service/FacilityService.java — bodyToMono(KricToiletRawResponse.class)로 역직렬화 후 response.body()를 List로 처리

변경된 스니펫:

List<KricToiletRawItem> body
src/main/java/com/wayble/server/direction/service/TransportationService.java (2)

290-292: 환승 횟수 제한 변경 확인 필요

환승 횟수 제한이 4회에서 3회로 줄었습니다. 이는 사용자 경험에 영향을 줄 수 있는 중요한 변경사항입니다. 의도된 변경인지 확인이 필요합니다.

비즈니스 요구사항과 이 변경이 일치하는지, 그리고 사용자 경험에 미치는 영향을 고려했는지 확인해주세요.


593-603: 도보 거리 계산 로직 개선됨

고정값 0 대신 실제 하버사인 거리를 계산하여 도보 거리를 설정하도록 개선되었습니다. 더 정확한 거리 정보를 제공할 수 있게 되었습니다.

src/main/java/com/wayble/server/direction/service/FacilityService.java (5)

47-55: 휠체어 정보 처리 로직 개선됨

routeId 기반으로 휠체어 정보를 조회하고 위치 정보를 수집하는 로직이 추가되었습니다. null 체크와 빈 문자열 처리가 적절하게 구현되었습니다.


90-90: 파라미터명 변경 확인 필요

railOprLsttCdrailOprIsttCd로 변경되었습니다. 이것이 의도된 변경인지, 오타인지 확인이 필요합니다.

KRIC API 문서를 확인하여 올바른 파라미터명이 railOprIsttCd인지 railOprLsttCd인지 검증해주세요.


104-111: 개선된 null 체크 로직

API 응답과 body에 대한 체계적인 null 체크가 추가되어 NullPointerException을 방지할 수 있게 되었습니다.


87-87: 확인 완료 — KRIC API 엔드포인트가 /openapi/vulnerableUserInfo/stationDisabledToilet로 맞습니다

KRIC 공개 문서에서 역사별 장애인 화장실 조회 엔드포인트가 해당 경로로 표기되어 있으며(serviceKey, format, railOprIsttCd, lnCd, stinCd 등 파라미터도 명시됨). (출처: https://data.kric.go.kr/rips/M_01_02/detail.do?id=432&operation=stationDisabledToilet&service=vulnerableUserInfo)

  • 수정 불필요: src/main/java/com/wayble/server/direction/service/FacilityService.java — 라인 87

37-37: getNodeInfo 시그니처 변경 검증 완료 — 호출부가 모두 업데이트되어 있음

저장소 전체 검색 결과, 선언부와 1곳의 호출만 존재하며 호출부는 routeId 인자를 함께 전달하고 있습니다.

  • 선언: src/main/java/com/wayble/server/direction/service/FacilityService.java:37 — public TransportationResponseDto.NodeInfo getNodeInfo(Long nodeId, Long routeId)
  • 호출: src/main/java/com/wayble/server/direction/service/TransportationService.java:643 — facilityService.getNodeInfo(currentEdge.getStartNode().getId(), currentEdge.getRoute().getRouteId());

따라서 추가 조치 불필요합니다.

Comment on lines +13 to +16
@Query("SELECT f FROM Facility f " +
"LEFT JOIN FETCH f.lifts " +
"WHERE f.id = :nodeId")
Optional<Facility> findByNodeId(@Param("nodeId") Long nodeId);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

FETCH JOIN + 단건 조회에서 DISTINCT 누락 시 NonUniqueResultException 위험

LEFT JOIN FETCH f.lifts로 다대일 확대 후 단건 반환 시 중복 로우가 생길 수 있습니다. SELECT DISTINCT를 붙여 중복을 제거하지 않으면 JPA가 단건 결과를 집계하지 못해 NonUniqueResultException이 발생할 수 있습니다.

다음과 같이 DISTINCT를 추가해주세요.

-    @Query("SELECT f FROM Facility f " +
+    @Query("SELECT DISTINCT f FROM Facility f " +
            "LEFT JOIN FETCH f.lifts " +
            "WHERE f.id = :nodeId")
     Optional<Facility> findByNodeId(@Param("nodeId") Long nodeId);
📝 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
@Query("SELECT f FROM Facility f " +
"LEFT JOIN FETCH f.lifts " +
"WHERE f.id = :nodeId")
Optional<Facility> findByNodeId(@Param("nodeId") Long nodeId);
@Query("SELECT DISTINCT f FROM Facility f " +
"LEFT JOIN FETCH f.lifts " +
"WHERE f.id = :nodeId")
Optional<Facility> findByNodeId(@Param("nodeId") Long nodeId);
🤖 Prompt for AI Agents
In src/main/java/com/wayble/server/direction/repository/FacilityRepository.java
around lines 13 to 16, the JPQL uses LEFT JOIN FETCH f.lifts which can produce
duplicate rows for a single Facility and cause NonUniqueResultException on a
single-result query; update the query to use SELECT DISTINCT f (i.e., prefix the
select with DISTINCT) so duplicates are eliminated and the Optional<Facility>
single-result retrieval is safe.

try {
if (currentEdge.getStartNode() != null) {
TransportationResponseDto.NodeInfo nodeInfo = facilityService.getNodeInfo(currentEdge.getStartNode().getId());
TransportationResponseDto.NodeInfo nodeInfo = facilityService.getNodeInfo(currentEdge.getStartNode().getId(), currentEdge.getRoute().getRouteId());
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

API 서명 변경 확인 필요

facilityService.getNodeInfo()가 이제 두 개의 파라미터 (nodeId, routeId)를 받도록 변경되었습니다. currentEdge.getRoute()가 null일 경우 NullPointerException이 발생할 수 있습니다.

-TransportationResponseDto.NodeInfo nodeInfo = facilityService.getNodeInfo(currentEdge.getStartNode().getId(), currentEdge.getRoute().getRouteId());
+Route route = currentEdge.getRoute();
+Long routeId = route != null ? route.getRouteId() : null;
+TransportationResponseDto.NodeInfo nodeInfo = facilityService.getNodeInfo(currentEdge.getStartNode().getId(), routeId);
📝 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
TransportationResponseDto.NodeInfo nodeInfo = facilityService.getNodeInfo(currentEdge.getStartNode().getId(), currentEdge.getRoute().getRouteId());
Route route = currentEdge.getRoute();
Long routeId = route != null ? route.getRouteId() : null;
TransportationResponseDto.NodeInfo nodeInfo = facilityService.getNodeInfo(currentEdge.getStartNode().getId(), routeId);

Comment on lines 737 to 760
int transferCount = 0;
for (int i = 0; i < steps.size() - 1; i++) {
TransportationResponseDto.Step currentStep = steps.get(i);
TransportationResponseDto.Step nextStep = steps.get(i + 1);

if (currentStep.mode() != DirectionType.WALK && nextStep.mode() != DirectionType.WALK) {
if (currentStep.mode() == nextStep.mode() &&
currentStep.routeName() != null && nextStep.routeName() != null &&
!currentStep.routeName().equals(nextStep.routeName())) {
transferCount++;
} else if (currentStep.mode() != nextStep.mode()) {
transferCount++;
DirectionType previousMode = null;
String previousRouteName = null;

for (TransportationResponseDto.Step step : steps) {
if (step.mode() != DirectionType.WALK && step.mode() != DirectionType.FROM_WAYPOINT && step.mode() != DirectionType.TO_WAYPOINT) {
if (previousMode != null) {
if (previousMode == step.mode() &&
previousRouteName != null && step.routeName() != null &&
!previousRouteName.equals(step.routeName())) {
transferCount++;
} else if (previousMode == step.mode() &&
previousRouteName != null && step.routeName() != null &&
previousRouteName.equals(step.routeName())) {
transferCount++;
} else if (previousMode != step.mode()) {
transferCount++;
}
}
previousMode = step.mode();
previousRouteName = step.routeName();
}
}
return transferCount;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

환승 횟수 계산 로직의 복잡성

새로운 환승 횟수 계산 로직이 복잡하고 이해하기 어렵습니다. 특히 Lines 744-754에서 같은 모드와 같은 노선명을 가진 경우에도 환승으로 카운트하는 로직이 의도된 것인지 확인이 필요합니다.

Lines 744-751의 조건문이 논리적으로 올바르지 않습니다:

  • 같은 모드, 같은 노선명일 때도 환승으로 카운트 (Lines 749-751)
  • 같은 모드, 다른 노선명일 때도 환승으로 카운트 (Lines 745-747)

이는 항상 환승으로 카운트되는 문제가 있습니다. 다음과 같이 수정을 제안합니다:

-if (previousMode == step.mode() && 
-    previousRouteName != null && step.routeName() != null &&
-    !previousRouteName.equals(step.routeName())) {
-    transferCount++;
-} else if (previousMode == step.mode() && 
-    previousRouteName != null && step.routeName() != null &&
-    previousRouteName.equals(step.routeName())) {
-    transferCount++;
-} else if (previousMode != step.mode()) {
+// 모드가 다르거나 같은 모드에서 노선이 바뀔 때만 환승
+if (previousMode != step.mode() || 
+    (previousMode == step.mode() && 
+     previousRouteName != null && step.routeName() != null &&
+     !previousRouteName.equals(step.routeName()))) {
     transferCount++;
 }
📝 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
int transferCount = 0;
for (int i = 0; i < steps.size() - 1; i++) {
TransportationResponseDto.Step currentStep = steps.get(i);
TransportationResponseDto.Step nextStep = steps.get(i + 1);
if (currentStep.mode() != DirectionType.WALK && nextStep.mode() != DirectionType.WALK) {
if (currentStep.mode() == nextStep.mode() &&
currentStep.routeName() != null && nextStep.routeName() != null &&
!currentStep.routeName().equals(nextStep.routeName())) {
transferCount++;
} else if (currentStep.mode() != nextStep.mode()) {
transferCount++;
DirectionType previousMode = null;
String previousRouteName = null;
for (TransportationResponseDto.Step step : steps) {
if (step.mode() != DirectionType.WALK && step.mode() != DirectionType.FROM_WAYPOINT && step.mode() != DirectionType.TO_WAYPOINT) {
if (previousMode != null) {
if (previousMode == step.mode() &&
previousRouteName != null && step.routeName() != null &&
!previousRouteName.equals(step.routeName())) {
transferCount++;
} else if (previousMode == step.mode() &&
previousRouteName != null && step.routeName() != null &&
previousRouteName.equals(step.routeName())) {
transferCount++;
} else if (previousMode != step.mode()) {
transferCount++;
}
}
previousMode = step.mode();
previousRouteName = step.routeName();
}
}
return transferCount;
int transferCount = 0;
DirectionType previousMode = null;
String previousRouteName = null;
for (TransportationResponseDto.Step step : steps) {
if (step.mode() != DirectionType.WALK && step.mode() != DirectionType.FROM_WAYPOINT && step.mode() != DirectionType.TO_WAYPOINT) {
if (previousMode != null) {
// 모드가 다르거나 같은 모드에서 노선이 바뀔 때만 환승
if (previousMode != step.mode() ||
(previousMode == step.mode() &&
previousRouteName != null && step.routeName() != null &&
!previousRouteName.equals(step.routeName()))) {
transferCount++;
}
}
previousMode = step.mode();
previousRouteName = step.routeName();
}
}
return transferCount;

@hyoinYang hyoinYang merged commit da5d82b into main Aug 15, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release 프로덕션 서버에 배포

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants