Skip to content

Conversation

@hyoinYang
Copy link
Contributor

@hyoinYang hyoinYang commented Aug 15, 2025

✔️ 연관 이슈

📝 작업 내용

kric api의 안정성 강화 + 환승 횟수 로직 정교화 & 횟수 제한 강화

스크린샷 (선택)

Summary by CodeRabbit

  • 신기능

    • 경로 상세에 보행 거리(미터) 표시
    • 노선별 휠체어 위치 정보 제공
    • 환승 카운트 로직 정교화
  • 개선

    • 경로 추천 기준 조정(허용 환승 수 축소로 더 간결한 경로)
    • 지하철 정보 누락 시 기본값 제공으로 일관성 강화
    • 접근성/화장실 정보 집계 품질 개선
    • 외부 연동 재시도·타임아웃 적용으로 안정성 향상
  • 버그 수정

    • 버스/지하철 정보 조회 실패 시 로깅 수준 보정
    • 특정 상황에서의 예외(NPE) 예방
  • 문서

    • 한국어 README 추가 및 서비스/아키텍처 링크 정리

@hyoinYang hyoinYang self-assigned this Aug 15, 2025
@hyoinYang hyoinYang added the 🛠️ fix 기능 오류 및 코드 개선이 필요한 곳 수정 label Aug 15, 2025
@coderabbitai
Copy link

coderabbitai bot commented Aug 15, 2025

Walkthrough

KRIC 연동 로직과 WebClient 설정을 수정하고, 환승 카운트/필터링 로직을 변경했습니다. KRIC DTO 스키마를 갱신하고 응답 파싱 경로를 교체했습니다. 시설/노드 조회 흐름을 재구성해 routeId 기반 휠체어 위치를 포함했습니다. 엔티티/리포지토리를 추가·변경했으며 README(KO)를 추가했습니다.

Changes

Cohort / File(s) Summary
Documentation
README.md
프로젝트/BE 구조/리소스/링크를 포함한 한국어 README 추가.
HTTP Client Config (KRIC)
src/main/java/.../common/config/WebClientConfig.java
KRIC WebClient에 메모리 제한(2MB), 15초 타임아웃, WebClientRequestException 대상 백오프 재시도(3회) 필터 추가.
DTO: TransportationResponse
src/main/java/.../direction/dto/response/TransportationResponseDto.java
Step 필드명 from→to 변경, WALK의 moveNumber 주석 보완, SubwayInfo/NodeInfo의 wheelchair/elevator 타입을 List→List으로 변경.
DTO: KRIC Toilet
.../external/kric/dto/KricToiletRawItem.java,.../external/kric/dto/KricToiletRawResponse.java,.../external/kric/dto/KricToiletRawBody.java
KricToiletRawItem 필드 확장(역사/노선/위치 상세 등). RawResponse.body 타입을 KricToiletRawBody→List로 변경. KricToiletRawBody 제거.
Entities
.../entity/transportation/Facility.java,.../entity/transportation/Route.java,.../entity/transportation/Wheelchair.java
Facility의 @GeneratedValue 제거(수동 PK 할당 전제). Route에 wheelchairs(OneToMany) 추가. Wheelchair 엔티티 신설(route, wheelchairLocation).
Repositories
.../repository/FacilityRepository.java,.../repository/WheelchairInfoRepository.java
FacilityRepository.findByNodeId를 LEFT JOIN FETCH lifts JPQL로 변경. WheelchairInfoRepository 신설 및 findByRouteId 쿼리 추가.
Services
.../service/FacilityService.java,.../service/TransportationService.java
FacilityService.getNodeInfo 시그니처 변경(nodeId, routeId). routeId로 Wheelchair 조회/적용. KRIC 호출 엔드포인트/코드명 변경 및 널가드/로깅 보강. TransportationService에서 환승 임계값 3으로 하향, 환승 카운트 로직 재작성, WALK 구간 거리 계산(haversine), 지하철 시작 노드 null 시 기본값 설정, 에러 로깅 강화.

Sequence Diagram(s)

sequenceDiagram
  participant TS as TransportationService
  participant FS as FacilityService
  participant NR as NodeRepository
  participant FR as FacilityRepository
  participant WR as WheelchairInfoRepository
  participant KRIC as KRIC API

  TS->>FS: getNodeInfo(nodeId, routeId)
  FS->>NR: findById(nodeId)
  NR-->>FS: Node?
  alt routeId provided
    FS->>WR: findByRouteId(routeId)
    WR-->>FS: List<Wheelchair>
  end
  FS->>FR: findByNodeId(nodeId) (fetch lifts)
  FR-->>FS: Facility?
  alt Facility with codes
    FS->>KRIC: GET /openapi/vulnerableUserInfo/stationDisabledToilet
    KRIC-->>FS: List<KricToiletRawItem> or null
    FS-->>TS: NodeInfo(List<String> wheelchair/elevator, restroom map)
  else no facility/codes
    FS-->>TS: NodeInfo with available data
  end
Loading
sequenceDiagram
  participant TS as TransportationService
  participant Geo as Haversine
  participant FS as FacilityService

  TS->>TS: 필터(환승 ≤ 3)
  TS->>TS: 환승 카운트(모드/노선명 변화 기준, 웨이포인트 제외)
  TS->>Geo: WALK 구간 시작/끝 좌표
  Geo-->>TS: 거리(m)
  TS->>FS: getNodeInfo(startNodeId, routeId)
  FS-->>TS: NodeInfo
  TS-->>TS: Step 생성(SUBWAY/BUS/WALK 등)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Assessment against linked issues

Objective Addressed Explanation
KRIC API 응답 수정 및 타임아웃 추가 (#150)
환승 횟수 변경 (#150)
환승 카운트 로직 수정 (#150)
KRIC 관련 로깅을 자세하게 변경 (#150)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
휠체어 엔티티 및 매핑 추가 (src/main/java/.../entity/transportation/Wheelchair.java, Route.java: wheelchairs 필드) 링크된 이슈에는 휠체어 데이터 모델 확장이 포함되지 않음.
WheelchairInfoRepository 신설 및 routeId 기반 조회 (src/main/java/.../repository/WheelchairInfoRepository.java) 이슈 범위는 KRIC/환승 로직에 국한되며, DB 조회로 휠체어 위치를 추가하는 기능은 명시되지 않음.
FacilityService에서 routeId로 휠체어 위치 리스트 반영 (src/main/java/.../service/FacilityService.java) 목적과 무관한 기능 확장으로 보이며 이슈에 언급이 없음.
Facility PK 생성 전략 변경 (@GeneratedValue 제거) (src/main/java/.../entity/transportation/Facility.java) KRIC/환승 로직 변경과 직접 관련이 없고 데이터 영속성 전략 변경은 범위 외로 보임.

Possibly related PRs

Suggested labels

🔧 refactor

Suggested reviewers

  • seung-in-Yoo
  • KiSeungMin

Poem

봄바람 타고 코드를 핥—짝, 토끼 출동! 🐰
환승 셋, 걸음은 미터로 또랑또랑 표기하고,
KRIC은 타임아웃에 살포시 재시도—슉!
화장실 표도 정갈히, 로그는 또렷또렷.
길찾기 숲에 당근 깃발 펄럭—출발!

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 feature/hyoin

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 (1)
src/main/java/com/wayble/server/direction/dto/response/TransportationResponseDto.java (1)

51-54: LocationInfo 정의는 코드베이스 내 참조 없음 — 제거 권장

rg 검색 결과 해당 심볼은 정의된 파일 외에 참조가 없습니다. 사용되지 않는다면 제거하세요.

  • 파일: src/main/java/com/wayble/server/direction/dto/response/TransportationResponseDto.java — 삭제 후보(라인 대략 51–54)

제안 삭제(diff):

-    public record LocationInfo(
-            Double latitude,
-            Double longitude
-    ) {}

외부(다른 저장소/클라이언트)에서 사용될 가능성이 있으면 삭제 전 확인 바랍니다.

🧹 Nitpick comments (25)
README.md (11)

1-3: 문서 추가 자체는 좋습니다

프로젝트 전반(개요, 팀, 스택, 아키텍처, 폴더 구조 등)을 한 곳에 모아둔 점이 유용합니다. 아래는 마크다운 렌더링 품질과 링크 신뢰성을 높이기 위한 가벼운 손보기 제안입니다.


12-13: 헤딩 레벨 일관성(HD001) 정리 제안

H1 다음 바로 H3를 사용하고(라인 12–13), H2 다음 H4를 사용(라인 188)해 markdownlint가 경고합니다. 각 위치에서 한 단계씩만 증가하도록 조정하면 좋습니다.

아래처럼 변경해 주세요:

-### [🛠️Wayble 서비스 링크 바로가기](https://wayble.site)
-### [🎬Wayble 노션 링크 바로가기](https://www.notion.so/wayble-20475cf0b87b806d9473feb579ab23e0)
+## [🛠️Wayble 서비스 링크 바로가기](https://wayble.site)
+## [🎬Wayble 노션 링크 바로가기](https://www.notion.so/wayble-20475cf0b87b806d9473feb579ab23e0)
-#### [🛠️Wayble 기능명세 링크](https://www.notion.so/API-21d75cf0b87b80248a0ec55c6134ad20)
+### [🛠️Wayble 기능명세 링크](https://www.notion.so/API-21d75cf0b87b80248a0ec55c6134ad20)

Also applies to: 188-188


15-25: 목차 앵커 불일치(MD051) 수정 제안

목차의 앵커가 실제 헤딩과 다릅니다. 특히 “BE 폴더 구조”, “BE 시스템 구성도”, “상세 기능” 등이 링크 깨짐 원인입니다. 아래처럼 실제 헤딩에 맞춰 정리해주세요. “상세 기능” 섹션은 본문에 부재하므로 임시 제거 또는 섹션 추가 중 선택이 필요합니다.

-### 📂 Content
-- [🔎 팀 소개](#팀-소개)
-- [🔎 기술 스택](#기술-스택)
-- [🔎 서비스 고안 배경](#서비스-고안-배경)
-- [🔎 주요 기능](#주요-기능)
-- [🔎 상세 기능](#상세-기능)
-- [🔎 BE 폴더 구조](#BE-폴더-구조)
-- [🔎 BE 시스템 구성도](#BE-시스템-구성)
-- [🔎 데이터베이스 구조](#데이터베이스-구조)
-- [🔎 api 명세](#api-명세)
+### 📂 Content
+- [🔎 팀 소개](#-팀-소개)
+- [🔎 기술 스택](#-기술-스택)
+- [🔎 서비스 고안 배경](#-서비스-고안-배경)
+- [🔎 주요 기능](#-주요-기능)
+<!-- 상세 기능 섹션이 본문에 없으므로 일단 비활성화하거나 본문 섹션을 추가하세요 -->
+<!-- - [🔎 상세 기능](#-상세-기능) -->
+- [🔎 폴더 구조](#-폴더-구조)
+- [🔎 시스템 구성도](#-시스템-구성도)
+- [🔎 데이터베이스 구조](#-데이터베이스-구조)
+- [🔎 API 명세](#-api-명세)

원하시면 실제 GitHub 앵커 규칙에 맞춰 전체 헤딩→앵커 매핑 표를 정리해드릴게요.


4-4: 굵은 글씨 대신 헤딩 사용(MD036)으로 가독성 개선

현재 굵은 글씨로 사실상 헤딩 역할을 하는 라인이 다수 있습니다. 헤딩으로 변경하면 목차/접근성/렌더링 품질이 좋아집니다.

-**사용자를 위한 맞춤형 배리어프리 서비스 Wayble**
+## 사용자를 위한 맞춤형 배리어프리 서비스 Wayble
-**WAYBLE은**
+### WAYBLE은
-**장애 유형·이동 수단별 최적화된 경로 탐색**
+### 장애 유형·이동 수단별 최적화된 경로 탐색
-**접근성 필터 기반 장소 추천**
+### 접근성 필터 기반 장소 추천
-**장애인 참여형 접근성 정보 수집·공유**
+### 장애인 참여형 접근성 정보 수집·공유
-**1. 지도 기반 접근 가능 장소 검색**
+### 1) 지도 기반 접근 가능 장소 검색
-**2. 맞춤형 경로 안내**
+### 2) 맞춤형 경로 안내
-**3. 접근성 리뷰 작성·열람**
+### 3) 접근성 리뷰 작성·열람
-**4. 마이 플레이스**
+### 4) 마이 플레이스

Also applies to: 81-81, 90-90, 92-92, 94-94, 101-101, 106-106, 114-114, 118-118


36-41: 팀 표 마크다운 파이프 스타일(MD055) 정리

표 행 끝의 트레일링 파이프가 없어 lint가 경고합니다. 아래처럼 모두 행 끝에 파이프를 추가해 주세요.

-| 기승민 (Lead)                                  | 양효인                               | 유승인                                 | 이원준                                           | 주정빈                               |   
-| ---------------------------------------- | ------------------------------------ | -------------------------------------- | ------------------------------------------------ | -------------------------------------- | 
-| ![profile](https://avatars.githubusercontent.com/u/67568824?v=4) | ![profile](https://avatars.githubusercontent.com/u/144425658?v=4) |![profile](https://avatars.githubusercontent.com/u/144124353?v=4)|![profile](https://avatars.githubusercontent.com/u/202200191?v=4) | ![profile](https://avatars.githubusercontent.com/u/166782961?v=4) 
-| BE                                     |  BE                                  |  BE                                     |  BE                                              |  BE                                | 
-| [@KiSeungMin](https://github.com/KiSeungMin) |[@hyoinYang](https://github.com/hyoinYang)|[@seung-in-Yoo](https://github.com/seung-in-Yoo)  | [@wonjun-lee-fcwj245](https://github.com/wonjun-lee-fcwj245) |[@zyovn](https://github.com/zyovn) |
+| 기승민 (Lead)                                  | 양효인                               | 유승인                                 | 이원준                                           | 주정빈                               |
+| ---------------------------------------------- | ------------------------------------ | -------------------------------------- | ------------------------------------------------ | ------------------------------------ |
+| ![profile](https://avatars.githubusercontent.com/u/67568824?v=4) | ![profile](https://avatars.githubusercontent.com/u/144425658?v=4) | ![profile](https://avatars.githubusercontent.com/u/144124353?v=4) | ![profile](https://avatars.githubusercontent.com/u/202200191?v=4) | ![profile](https://avatars.githubusercontent.com/u/166782961?v=4) |
+| BE                                             | BE                                   | BE                                     | BE                                              | BE                                   |
+| [@KiSeungMin](https://github.com/KiSeungMin)   | [@hyoinYang](https://github.com/hyoinYang) | [@seung-in-Yoo](https://github.com/seung-in-Yoo) | [@wonjun-lee-fcwj245](https://github.com/wonjun-lee-fcwj245) | [@zyovn](https://github.com/zyovn) |

추가로 표 위/아래에 빈 줄 하나씩을 두면 가독성이 더 좋아집니다(MD058).


44-56: “기술 스택” 표 주변에 빈 줄 추가(MD058)

표 위/아래에 빈 줄이 없어 lint 경고가 납니다. 한 줄씩 추가해주세요.

-## 🔎 기술 스택
-
+## 🔎 기술 스택
+
 | Category             | Stack                                                                                                                                                                                                                                                                       |
 ...
-| Version Control      | ![Git](https://img.shields.io/badge/Git-F05032?style=for-the-badge&logo=git&logoColor=white) ![GitHub](https://img.shields.io/badge/GitHub-181717?style=for-the-badge&logo=github&logoColor=white) |
-<br>
+| Version Control      | ![Git](https://img.shields.io/badge/Git-F05032?style=for-the-badge&logo=git&logoColor=white) ![GitHub](https://img.shields.io/badge/GitHub-181717?style=for-the-badge&logo=github&logoColor=white) |
+
+<br>

136-136: 코드 블록에 언어 지정(MD040)

폴더 트리 코드 블록에 언어를 지정하면 렌더링/복사성이 좋아집니다. 일반 텍스트라면 text를 권장합니다.

-```
+```text

96-96: 플레이스홀더 문구 제거 또는 보강

“(채우기)” 플레이스홀더는 독자에게 혼란을 줄 수 있습니다. 작성 예정이라면 “준비 중” 등으로 명시하거나 항목을 일단 제거하는 것이 깔끔합니다.

-(채우기)
+준비 중

Also applies to: 124-124


155-161: 민감 파일 안내 문구 관련 보안 점검

README에 application_secret.yml, keystore.p12 등 민감 파일이 명시되어 있습니다. 실제 레포에 커밋되지 않도록 .gitignore/배포 파이프라인 시크릿 관리가 되어있는지 재확인 부탁드립니다.

필요 시:

  • .gitignore에 해당 파일 추가
  • 운영/배포는 GitHub Actions Secrets, Parameter Store, Secrets Manager 등으로 대체
  • README에는 “개발 환경에서만 필요, 저장소에 커밋하지 말 것” 주석 추가

186-191: API 명세 링크 표현 통일

섹션 제목이 “API 명세”이므로 링크 텍스트도 대소문자/표현을 통일하면 좋습니다. 위 헤딩 레벨 조정과 함께 반영하면 깔끔합니다.

-#### [🛠️Wayble 기능명세 링크](https://www.notion.so/API-21d75cf0b87b80248a0ec55c6134ad20)
+### [🛠️Wayble API/기능 명세](https://www.notion.so/API-21d75cf0b87b80248a0ec55c6134ad20)

62-87: README에 PR 핵심 변경 요약 단락 추가 고려

이번 PR의 핵심(예: KRIC WebClient 타임아웃/리트라이, 환승 횟수 제한/카운트 로직 보강)이 실제 운영 관점에서 중요하므로, 간단한 “최근 변경 사항” 혹은 CHANGELOG 링크를 README 상단에 추가하면 온보딩이 수월합니다.

원하시면 “최근 변경 사항” 박스(한두 문단)와 관련 이슈/PR 링크 템플릿을 바로 만들어 드리겠습니다.

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

34-34: in-memory 제한(2MB) 설정은 적절합니다. 다만 프로퍼티로 외부화하는 것을 고려해주세요.

KRIC 응답 페이로드가 커질 수 있으므로 운영 중 튜닝 가능성을 위해 kric.api.max-in-memory-size 같은 프로퍼티로 노출해 두면 유연성이 올라갑니다.


35-38: 재시도 범위를 5xx/Timeout까지 확장하고, 지터/최대 backoff를 추가하는 것이 안정성 측면에서 유리합니다.

현재는 WebClientRequestException에만 재시도하며 5xx는 재시도되지 않습니다. 또한 Timeout도 재시도 대상이 아닙니다. 아래와 같이 5xx를 예외로 승격하고, Timeout/ResponseException도 재시도하며, 지터/최대 backoff를 추가하는 것을 권장합니다. 또한 비멱등 요청 오발 재시도를 방지하기 위해 GET 메서드에만 재시도하도록 제한합니다.

-                .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) -> next.exchange(request)
+                        .flatMap(response -> {
+                            if (response.statusCode().is5xxServerError()) {
+                                return reactor.core.publisher.Mono.error(
+                                        new org.springframework.web.reactive.function.client.WebClientResponseException(
+                                                "5xx from KRIC: " + response.statusCode(),
+                                                response.rawStatusCode(),
+                                                response.statusCode().getReasonPhrase(),
+                                                null, null, null
+                                        )
+                                );
+                            }
+                            return reactor.core.publisher.Mono.just(response);
+                        })
+                        .timeout(java.time.Duration.ofSeconds(15))
+                        .retryWhen(
+                                reactor.util.retry.Retry.backoff(3, java.time.Duration.ofSeconds(1))
+                                        .maxBackoff(java.time.Duration.ofSeconds(5))
+                                        .jitter(0.5)
+                                        .filter(throwable ->
+                                                request.method() == org.springframework.http.HttpMethod.GET && (
+                                                throwable instanceof org.springframework.web.reactive.function.client.WebClientRequestException
+                                                        || throwable instanceof java.util.concurrent.TimeoutException
+                                                        || throwable instanceof org.springframework.web.reactive.function.client.WebClientResponseException
+                                                )
+                                        )
+                        ))

추가로, 연결/응답 타임아웃은 Netty 커넥터 레벨에서도 설정해 두면(예: connect timeout, response timeout) 보다 일관되게 동작합니다. 필요하시면 적용 코드도 드리겠습니다.

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

6-16: 필드 확장 반영 좋습니다. 다만 JSON 바인딩 키 스펙을 한 번 더 확인해주세요.

KRIC 응답의 필드명이 정확히 현재 레코드 파라미터명과 일치하지 않으면 매핑이 실패할 수 있습니다(대소문자/철자 포함). 확실히 하려면 @JsonProperty로 명시 바인딩을 권장합니다.

예시(필요한 모든 필드에 동일 패턴 적용):

-        String railOprIsttCd,
-        String lnCd,
+        @com.fasterxml.jackson.annotation.JsonProperty("railOprIsttCd") String railOprIsttCd,
+        @com.fasterxml.jackson.annotation.JsonProperty("lnCd") String lnCd,
         String stinCd,
-        String grndDvNm,
-        String stinFlor,
-        String gateInotDvNm,
-        String exitNo,
-        String dtlLoc,
-        String mlFmlDvNm,
-        String toltNum,
-        String diapExchNum
+        @com.fasterxml.jackson.annotation.JsonProperty("grndDvNm") String grndDvNm,
+        @com.fasterxml.jackson.annotation.JsonProperty("stinFlor") String stinFlor,
+        @com.fasterxml.jackson.annotation.JsonProperty("gateInotDvNm") String gateInotDvNm,
+        @com.fasterxml.jackson.annotation.JsonProperty("exitNo") String exitNo,
+        @com.fasterxml.jackson.annotation.JsonProperty("dtlLoc") String dtlLoc,
+        @com.fasterxml.jackson.annotation.JsonProperty("mlFmlDvNm") String mlFmlDvNm,
+        @com.fasterxml.jackson.annotation.JsonProperty("toltNum") String toltNum,
+        @com.fasterxml.jackson.annotation.JsonProperty("diapExchNum") String diapExchNum

실제 샘플 응답(JSON)을 기반으로 키 일치 여부를 확인해 주세요. 필요 시 샘플 기반으로 주석/테스트도 추가 가능했습니다.


3-3: 불필요한 import 제거

record는 접근자(getter)를 자동 생성하므로 lombok.Getter는 불필요합니다. 제거하여 정리하는 것을 권장합니다.

-import lombok.Getter;
src/main/java/com/wayble/server/direction/dto/response/TransportationResponseDto.java (2)

46-47: List<String>로의 변경은 단순하지만, 포맷 표준화 또는 VO 도입을 고려해 주세요.

문자열 리스트는 포맷이 팀/클라 간 쉽게 일탈될 수 있습니다. 최소한 예시/포맷 규칙(예: “상행·하행/호선/출구 번호/상세 위치” 등)을 스키마/문서에 명시하거나, 간단한 값 객체(예: FacilityLocation { String description; })를 두는 것을 권장합니다.

원한다면 Swagger 스키마 예시를 추가해 드릴 수 있습니다.


58-59: NodeInfo도 동일하게 포맷 표준화를 권장합니다.

List<String>로의 통일은 일관성을 주지만, 소비자 입장에서 위치 문자열의 문법이 통제되지 않으면 파싱/표시 이슈가 발생합니다. 간단한 VO 또는 명확한 문서화를 함께 고려해 주세요.

src/main/java/com/wayble/server/direction/entity/transportation/Route.java (1)

40-41: 연관관계 추가 방향 좋습니다. Lazy 로딩으로 기본 성능도 안전합니다.

Route 기준으로 Wheelchair를 조회해야 하는 요구 사항과 일치합니다. 다만 컬렉션 NPE 방지를 위해 기본 초기화를 고려할 수 있습니다.

-    private List<Wheelchair> wheelchairs;
+    private List<Wheelchair> wheelchairs = new java.util.ArrayList<>();

또한 영속성 전파/고아 객체 제거가 필요할지(작성/삭제를 Route를 통해 관리한다면 cascade = ALL, orphanRemoval = true) 도메인 요구사항에 맞게 판단해 주세요.

src/main/java/com/wayble/server/direction/repository/WheelchairInfoRepository.java (2)

11-15: 파생 쿼리 메서드로 간소화 가능 (@query 불필요)

Spring Data JPA의 파생 쿼리를 활용하면 @query 없이 동일 기능을 제공할 수 있습니다. 또한 타입 안정성과 유지보수성이 개선됩니다.

-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
+// @Query, @Param 불필요

 ...
-    @Query("SELECT w FROM Wheelchair w WHERE w.route.routeId = :routeId")
-    List<Wheelchair> findByRouteId(@Param("routeId") Long routeId);
+    List<Wheelchair> findAllByRoute_RouteId(Long routeId);

8-10: 불필요한 import 정리 제안

Optional을 사용하지 않으므로 제거해도 됩니다.

 import java.util.List;
-import java.util.Optional;
src/main/java/com/wayble/server/direction/service/TransportationService.java (1)

592-604: WALK 구간 실제 거리 반영 좋습니다

연속 WALK 구간을 실제 하버사인 거리로 계산해 Step에 반영한 점 좋습니다. 이후 정렬 로직(calculateWalkDistance)이 현재 상수(500m)를 사용하고 있어 실제 거리 기반으로 정렬되지 않는 점은 개선 여지가 있습니다. 필요 시 제가 반영 코드 제안드릴 수 있습니다.

추가 제안(참고용, 별도 변경 필요 영역):

// 제안: 실제 walkDistance를 합산하도록 변경
private int calculateWalkDistance(List<TransportationResponseDto.Step> route) {
    return route.stream()
        .filter(step -> step.mode() == DirectionType.WALK)
        .mapToInt(TransportationResponseDto.Step::moveNumber) // WALK에서는 moveNumber를 거리(m)로 사용 중
        .sum();
}
src/main/java/com/wayble/server/direction/entity/transportation/Wheelchair.java (1)

11-24: 쿼리 성능 향상용 인덱스 권장 (route_id)

findByRouteId 조회가 빈번하다면 route_id에 인덱스를 추가하는 것이 좋습니다. JPA로는 @table(indexes=…)로 지정 가능합니다.

-@Table(name = "wheelchair")
+@Table(
+    name = "wheelchair",
+    indexes = {
+        @Index(name = "idx_wheelchair_route", columnList = "route_id")
+    }
+)
src/main/java/com/wayble/server/direction/service/FacilityService.java (3)

37-55: 노드 존재 검증 및 경로별 휠체어 정보 병합: 방향성 OK

  • Node 존재 시에만 후속 처리를 수행하는 흐름 적절합니다.
  • routeId가 있을 때 노선별 휠체어 위치를 문자열로 트리밍 후 수집하는 로직도 깔끔합니다.

향후 elevator도 동일한 방식으로 채울 계획인지 확인 부탁드립니다. 현재는 항상 빈 리스트로 반환됩니다.

엘리베이터 정보도 Facilityelevators를 이용해 List<String>로 맵핑하는 보일러플레이트 코드를 제가 준비해 드릴까요?


59-71: Facility 조회 실패/정보 누락 로깅은 좋음 — 단, Repository 쿼리 의도 확인 필요

facilityRepository.findByNodeId(nodeId)는 내부적으로 f.id = :nodeId를 사용합니다. @mapsid로 동일하긴 하나, 의도를 명확히 하려면 f.node.id로 조건을 거는 편이 가독성상 안전합니다. Repository 쪽 코멘트 참고해 주세요.


97-103: WebClient 타임아웃 추가 권장

PR 목표에 ‘타임아웃 추가’가 포함되어 있습니다. 현재 .block()만 사용하고 있어 호출이 지연될 수 있습니다. Mono 레벨에서 타임아웃을 추가하세요.

             KricToiletRawResponse response = kricWebClient
                     .get()
                     .uri(uri)
                     .retrieve()
-                    .bodyToMono(KricToiletRawResponse.class)
+                    .bodyToMono(KricToiletRawResponse.class)
+                    .timeout(Duration.ofSeconds(3))
                     .block();

추가로, WebClient Bean 구성에서 커넥션/읽기 타임아웃을 설정해 두면 더욱 안전합니다.

추가 import (파일 상단에):

import java.time.Duration;
📜 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 253f65a and 6ee135d.

📒 Files selected for processing (13)
  • README.md (1 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/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)
💤 Files with no reviewable changes (2)
  • src/main/java/com/wayble/server/direction/entity/transportation/Facility.java
  • src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawBody.java
🧰 Additional context used
🧬 Code Graph Analysis (7)
src/main/java/com/wayble/server/common/config/WebClientConfig.java (1)
src/main/java/com/wayble/server/direction/external/kric/KricProperties.java (1)
  • ConfigurationProperties (5-10)
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/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/external/kric/dto/KricToiletRawResponse.java (2)
src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawBody.java (1)
  • KricToiletRawBody (5-7)
src/main/java/com/wayble/server/direction/external/opendata/dto/OpenDataResponse.java (1)
  • MsgBody (28-30)
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/TransportationService.java (2)
src/main/java/com/wayble/server/direction/service/WalkingService.java (1)
  • Slf4j (20-64)
src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java (1)
  • Service (16-170)
src/main/java/com/wayble/server/direction/service/FacilityService.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/Node.java (1)
  • Entity (13-79)
🪛 markdownlint-cli2 (0.17.2)
README.md

4-4: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


12-12: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)


16-16: Link fragments should be valid

(MD051, link-fragments)


17-17: Link fragments should be valid

(MD051, link-fragments)


18-18: Link fragments should be valid

(MD051, link-fragments)


19-19: Link fragments should be valid

(MD051, link-fragments)


20-20: Link fragments should be valid

(MD051, link-fragments)


21-21: Link fragments should be valid

(MD051, link-fragments)


22-22: Link fragments should be valid

(MD051, link-fragments)


23-23: Link fragments should be valid

(MD051, link-fragments)


24-24: Link fragments should be valid

(MD051, link-fragments)


38-38: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)


55-55: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


81-81: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


90-90: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


92-92: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


94-94: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


101-101: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


106-106: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


114-114: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


118-118: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


136-136: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


188-188: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4

(MD001, heading-increment)

🔇 Additional comments (6)
src/main/java/com/wayble/server/direction/external/kric/dto/KricToiletRawResponse.java (1)

6-6: KRIC 응답 스키마(body vs body.item) 변경 여부를 재확인해 주세요.

현재 bodyList<KricToiletRawItem>로 평탄화했습니다. 실제 KRIC 응답이 { "body": { "item": [...] } } 구조라면 역직렬화가 실패합니다. 반대로 { "body": [...] } 구조라면 지금 구현이 맞습니다.

만약 기존 구조(중첩)라면 아래처럼 유지하는 편이 안전합니다(참고 코드):

// KricToiletRawResponse.java
public record KricToiletRawResponse(
    KricToiletRawBody body
) {}

// KricToiletRawBody.java
public record KricToiletRawBody(
    @com.fasterxml.jackson.annotation.JsonProperty("item")
    java.util.List<KricToiletRawItem> item
) {}

실제 샘플 응답으로 검증이 필요하면 말씀 주세요. 테스트/매퍼 보완까지 함께 드릴 수 있습니다.

src/main/java/com/wayble/server/direction/dto/response/TransportationResponseDto.java (1)

23-23: 주석 업데이트 좋습니다.

WALK 단계에서 moveNumber가 “거리(미터)”일 수 있음을 명시해 혼동을 줄였습니다.

src/main/java/com/wayble/server/direction/service/TransportationService.java (2)

290-293: 환승 제한(3회 미만) 필터링 적용, 방향성 적절

PR 목표(환승 제한 강화)에 부합합니다. 이후 정렬 지표에 실제 도보 거리(아래 WALK step 계산) 반영도 고려해 보세요.


658-659: 에러 로그 레벨 상향 적절

실패 시 기본값으로 대체하고 error로 로깅 처리한 점, 장애 분석에 유리합니다.

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

113-115: 예외 로깅 형식 👍

식별자(stinCd, railOprIsttCd, lnCd)와 예외 메시지/스택을 함께 남겨 원인 분석에 유리합니다.


86-94: KRIC 파라미터명(railOprIsttCd) 확인 — 변경 불필요

KRIC "vulnerableUserInfo/stationDisabledToilet" API의 파라미터명은 railOprIsttCd가 맞습니다. 현재 코드에서는 queryParam 이름으로 "railOprIsttCd"를 사용하고 값으로 facility.getRailOprLsttCd()를 전달하고 있으므로 호출은 올바릅니다. (엔티티 필드명 railOprLsttCd는 DB 컬럼 rail_opr_lstt_cd와 매핑되어 네이밍이 다름)

수정이 필요한 위치(참고):

  • src/main/java/com/wayble/server/direction/service/FacilityService.java
    • getToiletInfo(): .queryParam("railOprIsttCd", facility.getRailOprLsttCd())
  • src/main/java/com/wayble/server/direction/entity/transportation/Facility.java
    • @column(name="rail_opr_lstt_cd") private String railOprLsttCd;

권장사항(선택): 네이밍 혼동 방지를 위해 필드 주석 추가나 이름 통일을 고려하세요.

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로 컬렉션을 조인하면서 단건(Optional<Facility>)을 반환하고 있는데, DISTINCT가 없어 동일 Facility가 중복 로우로 반환될 수 있습니다. JPA 구현에 따라 NonUniqueResultException이 발생할 수 있으므로 DISTINCT를 추가해 중복 제거가 필요합니다. 또한 메서드명은 nodeId로 찾는 의미인데 WHERE 절은 f.id를 사용하고 있어, 의도를 명확히 하려면 f.node.id를 사용하는 편이 좋습니다(@mapsid로 동등하긴 하나 가독성 관점에서 이점).

아래와 같이 수정 제안드립니다.

-    @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.node.id = :nodeId")
+    Optional<Facility> findByNodeId(@Param("nodeId") Long nodeId);

추가로, 현재 호출부(FacilityService)에서는 lifts를 실제로 사용하지 않으므로 성능이 민감하다면 fetch join 자체를 제거하거나 필요 시 elevators까지 함께 fetch join하는 방향을 검토해 주세요.

📝 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.node.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 query uses a collection fetch join (LEFT JOIN FETCH
f.lifts) while returning a single Optional<Facility>, which can yield duplicate
rows and cause NonUniqueResultException; change the JPQL to SELECT DISTINCT f
and update the WHERE clause to reference f.node.id = :nodeId for clarity; if
lifts are not needed by the caller consider removing the fetch join (or fetch
additional collections like elevators only when necessary) to avoid unnecessary
performance cost.

Comment on lines +643 to 656
TransportationResponseDto.NodeInfo nodeInfo = facilityService.getNodeInfo(currentEdge.getStartNode().getId(), currentEdge.getRoute().getRouteId());

subwayInfo = new TransportationResponseDto.SubwayInfo(
nodeInfo.wheelchair(),
nodeInfo.elevator(),
nodeInfo.accessibleRestroom()
);
} else {
subwayInfo = new TransportationResponseDto.SubwayInfo(
new ArrayList<>(),
new ArrayList<>(),
false
);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

NPE 위험: currentEdge.getRoute() null 체크 필요

facilityService.getNodeInfo(currentEdge.getStartNode().getId(), currentEdge.getRoute().getRouteId()) 호출 전 currentEdge.getRoute()가 null일 수 있습니다. 방어 코드가 없으므로 NPE 위험이 있습니다.

-                        TransportationResponseDto.NodeInfo nodeInfo = facilityService.getNodeInfo(currentEdge.getStartNode().getId(), currentEdge.getRoute().getRouteId());
+                        Long routeId = (currentEdge.getRoute() != null) ? currentEdge.getRoute().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());
subwayInfo = new TransportationResponseDto.SubwayInfo(
nodeInfo.wheelchair(),
nodeInfo.elevator(),
nodeInfo.accessibleRestroom()
);
} else {
subwayInfo = new TransportationResponseDto.SubwayInfo(
new ArrayList<>(),
new ArrayList<>(),
false
);
}
Long routeId = (currentEdge.getRoute() != null) ? currentEdge.getRoute().getRouteId() : null;
TransportationResponseDto.NodeInfo nodeInfo =
facilityService.getNodeInfo(currentEdge.getStartNode().getId(), routeId);
subwayInfo = new TransportationResponseDto.SubwayInfo(
nodeInfo.wheelchair(),
nodeInfo.elevator(),
nodeInfo.accessibleRestroom()
);
} else {
subwayInfo = new TransportationResponseDto.SubwayInfo(
new ArrayList<>(),
new ArrayList<>(),
false
);
}
🤖 Prompt for AI Agents
In src/main/java/com/wayble/server/direction/service/TransportationService.java
around lines 643 to 656, currentEdge.getRoute() may be null before calling
currentEdge.getRoute().getRouteId(), so add a null check for
currentEdge.getRoute() (or use Optional/null-safe access) and only call
facilityService.getNodeInfo(...) when the route is non-null; if null, fall back
to the existing else behavior (create SubwayInfo with empty lists and false) and
optionally log a warning or debug message to aid troubleshooting.

Comment on lines +738 to 759
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();
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

환승 카운트 로직이 사실상 매 스텝마다 +1; 의도와 불일치

현재 분기 구조상 동일 모드+동일 노선에서도 환승이 증가합니다. 일반적으로 첫 대중교통 탑승은 환승으로 보지 않고, 이후 모드 변경 또는 노선명이 달라질 때만 +1 해야 합니다.

아래와 같이 간결하고 의도에 맞게 수정 제안드립니다.

-        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();
-            }
-        }
+        for (TransportationResponseDto.Step step : steps) {
+            if (step.mode() == DirectionType.WALK
+                || step.mode() == DirectionType.FROM_WAYPOINT
+                || step.mode() == DirectionType.TO_WAYPOINT) {
+                continue;
+            }
+
+            if (previousMode == null) {
+                // 첫 탑승은 환승 아님
+                previousMode = step.mode();
+                previousRouteName = step.routeName();
+                continue;
+            }
+
+            if (step.mode() != previousMode) {
+                transferCount++;
+            } else {
+                if (previousRouteName != null && step.routeName() != null
+                    && !previousRouteName.equals(step.routeName())) {
+                    transferCount++;
+                }
+            }
+
+            previousMode = step.mode();
+            previousRouteName = step.routeName();
+        }
📝 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
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();
}
}
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) {
continue;
}
if (previousMode == null) {
// 첫 탑승은 환승 아님
previousMode = step.mode();
previousRouteName = step.routeName();
continue;
}
if (step.mode() != previousMode) {
transferCount++;
} else {
if (previousRouteName != null && step.routeName() != null
&& !previousRouteName.equals(step.routeName())) {
transferCount++;
}
}
previousMode = step.mode();
previousRouteName = step.routeName();
}

@hyoinYang hyoinYang changed the title [FIX] 연동 중 발생한 문제 해결 [FIX] kric api의 안정성 강화, 환승 횟수 로직 정교화 및 횟수 제한 강화 Aug 15, 2025
Copy link
Member

@zyovn zyovn left a comment

Choose a reason for hiding this comment

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

수고하셨습니다! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠️ fix 기능 오류 및 코드 개선이 필요한 곳 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants