Skip to content

Fix/arrival-and-departure-for-stop endpoint#962

Open
3rabiii wants to merge 23 commits into
OneBusAway:mainfrom
3rabiii:fix/arrival-departure-endpoint
Open

Fix/arrival-and-departure-for-stop endpoint#962
3rabiii wants to merge 23 commits into
OneBusAway:mainfrom
3rabiii:fix/arrival-departure-endpoint

Conversation

@3rabiii
Copy link
Copy Markdown
Contributor

@3rabiii 3rabiii commented May 18, 2026

Description

This PR addresses several critical functional parity gaps in the arrival-and-departure-for-stop API endpoint to ensure it matches the legacy OneBusAway implementation and strictly follows the API specification.

Key Changes

  • Gap 1 vehicleId: Formats the vehicle ID into the combined {agencyId}_{vehicleId} structure instead of returning the raw GTFS ID.

  • Gap 2: Sparse Sequence & Arrival/Departure Fix`: Computed a 0-based stop_ordinal in SQL to handle sparse GTFS sequences. This stable ordinal dynamically controls the arrival/departureEnabled flags and prevents 404 errors by safely matching client echo-requests.

  • Gap 3 routeShortName: Implements the 3-step narrative fallback for route short names.

  • Gap 4 tripHeadsign: Implements the stop-level narrative override for trip headsigns.

  • Gap 5 lastUpdateTime: Fixes the JSON serialization tag so it correctly emits 0 when there is no real-time vehicle data, instead of omitting the field entirely.

  • Gap 6 status & Cancelled Trips: Properly handles CANCELED schedule relationships by setting the entry status to "CANCELED", zeroing out predictions, stripping the vehicle ID, and omitting the tripStatus object.

  • Gap 7 Dynamic status: Maps non-scheduled GTFS-RT statuses (like ADDED or DUPLICATED) directly to the top-level entry status instead of unconditionally returning "default".

  • Gap 8 Prediction Zeroing: Ensures predictedArrivalTime and predictedDepartureTime are reset to 0 when predicted is false, rather than erroneously falling back to the scheduled times.

  • Gap 9 serviceDate Parsing: Supports YYYY-MM-DD date strings in the serviceDate parameter and correctly localizes dates to the agency's timezone to prevent calendar-day shifts.

  • Gap 10 time Parsing: Supports yyyy-MM-dd_HH-mm-ss datetime strings in the time parameter and localizes it to the agency's timezone.

  • Gap 11 includeReferences: Supports includeReferences=false for the singular endpoint to omit reference details (Agencies, Routes, Stops, Trips) from the response when requested.

  • Gap 12 stopSequence Search: Implements the expand-outward search algorithm for stopSequence matching, permitting tolerance to shifted indices from schedule modifications.

  • Gap 13 Closest Stop Visit: Resolves loop route ambiguity by selecting the closest scheduled stop visit using SQLite-driven absolute time difference calculations when stopSequence is absent.

  • Gap 14 blockTripSequence Fix: Accurately computes the 0-based trip sequence within a block by filtering active services. Updates the sentinel value to -1 for blockless trips and ensures the first trip (index 0) is correctly sent to the client.

  • Gap 15 Fix numberOfStopsAway: The numberOfStopsAway field in the arrival-and-departure-for-stop API was incorrectly returning 0 in Maglev. The previous implementation strictly relied on the GTFS-RT CurrentStopSequence to locate the vehicle, which is frequently unpopulated in many feeds

    • Changes:
      • Missing Data Fallback: Updated getNumberOfStopsAway to accept the tripStatus object.

      • New Block Sequence Helper: Introduced getBlockSequenceForStopID in block_sequence_helper.go to seamlessly translate a raw stopID into its global block sequence ordinal.

      • Distance-Based Lookup Fallback: Refactored buildTripStatusCore in trips_helper.go to compute shape points and distances earlier.

      • Formula Correction: Fixed the calculation logic to use a direct ordinal subtraction (target - vehicle) instead of the previous off-by-one formula (target - vehicle - 1).

      • Testing: Added new test cases (TestGetNumberOfStopsAway_Valid and TestGetNumberOfStopsAway_UsesTripStatusNextStop) to verify the correct ordinal differences and ensure both data paths resolve accurately.

Summary by CodeRabbit

  • Bug Fixes & Improvements

    • Vehicle ID formatting and prediction/cancellation handling improved; canceled trips clear prediction and vehicle info.
    • Stop indexing/ordinals are now zero‑based; nearest-stop selection favors time/distance proximity; numberOfStopsAway uses trip status when available and defaults to 0.
    • Request time/serviceDate parsing accepts Unix ms or formatted strings and localizes inputs more accurately.
    • Block/sequence fallbacks now return -1 for missing/invalid cases.
  • Chores

    • Minor JSON tag and cursor-close error handling fixes.
  • Tests

    • Expanded/reshaped tests for stop selection, trip/block indexing, DST edge cases, includeReferences behavior, and stop-sequence handling.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8402e1a9-38a7-49e7-83c9-bfbf05ac9a87

📥 Commits

Reviewing files that changed from the base of the PR and between 6ca0ece and de044be.

📒 Files selected for processing (2)
  • internal/restapi/arrival_and_departure_for_stop_handler.go
  • internal/restapi/block_sequence_helper.go

📝 Walkthrough

Walkthrough

Refactors arrival/departure handlers for ordinal-based stop selection, distance-based stop finding, SQL to return stop ordinals, request parsing/time localization, prediction/vehicle enrichment, response assembly (0-based ordinals and cancellation handling), model/test fixes, and minor DB row-close cleanup.

Changes

Arrival & Stop-selection Refactor

Layer / File(s) Summary
Database row defer-close cleanup
gtfsdb/block_layover_test.go, gtfsdb/stops_rtree.go
Standardize row Close defers to inline closures that ignore Close errors.
Model tag + small test assertions
internal/models/arrival_and_departure.go, internal/models/current_time_test.go, internal/models/trip_details_test.go
Remove non-standard ,omitzero JSON option on ArrivalAndDeparture.LastUpdateTime; update time-field tests to call Equal()/IsZero() on typed fields.
GTFS stop-time queries return ordinals
gtfsdb/query.sql, gtfsdb/query.sql.go
SQL and generated Go compute and return 0-based stop_ordinal and total_stops; GetTargetStopTimeWithTotalStops accepts CurrentTime and orders by closeness to it; sequence-based query matches computed ordinal.
Request parsing & localization
internal/restapi/arrival_and_departure_for_stop_handler.go
time and serviceDate accept unix-ms or formatted strings; UTC inputs are reconstructed into agency timezone preserving components.
Stop-sequence target lookup & outward search
internal/restapi/arrival_and_departure_for_stop_handler.go
Fetch target stop-time by ordinal/sequence; on no-row, expand outward from requested index to find a matching stop ordinal and retry; compute serviceMidnight/currentTime in agency TZ; use DB StopHeadsign.String.
Vehicle & prediction handling
internal/restapi/arrival_and_departure_for_stop_handler.go
Construct vehicleID using agency+vehicle ID, explicitly zero predicted times when no prediction exists, and change default numberOfStopsAway behavior when lookup returns nil.
Response field derivation & cancellation
internal/restapi/arrival_and_departure_for_stop_handler.go
Derive 0-based stopSequence, arrivalEnabled/departureEnabled, routeShortName/tripHeadsign overrides, entryStatus from trip status, and special "CANCELED" handling that clears prediction/vehicle/tripStatus and zeroes predicted times/lastUpdateTime; update reference assembly.
getNumberOfStopsAway & trips helper refactor
internal/restapi/arrival_and_departure_for_stop_handler.go, internal/restapi/trips_helper.go
Signature now accepts tripStatus; computation prefers tripStatus.NextStop. Trip helpers fetch shape points, compute projected actualDistance, add findStopsByDistance, set NextStop==ClosestStop for RT StopID/sequence, and remove old sequence-based helpers.
Block sequence & ordinal fallback
internal/restapi/block_sequence_helper.go
Compute block sequence by locating stop_sequence index in trip stop_times; fallback to rawSequenceToOrdinal when block data missing; expose helper and update getBlockSequenceForStopID.
Tests: handler & trips updates
internal/restapi/arrival_and_departure_for_stop_handler_test.go, internal/restapi/trips_helper_test.go, internal/restapi/calculate_block_trip_sequence_test.go
Update tests to expect zero-based ordinals, expand getNumberOfStopsAway coverage, add outward-search/closest-visit/includeReferences tests, add DST/shape/grouping tests, and remove old sequence-based test suites.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • fletcherw
  • Ahmedhossamdev
  • aaronbrethorst
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix/arrival-and-departure-for-stop endpoint' directly refers to the primary change: fixing the arrival-and-departure-for-stop API endpoint with multiple functional corrections.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@3rabiii 3rabiii marked this pull request as draft May 18, 2026 00:29
Copy link
Copy Markdown

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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/restapi/arrival_and_departure_for_stop_handler.go`:
- Around line 373-375: The code is deriving a zero-based stop ordinal from raw
GTFS stop_times.stop_sequence (stopSequenceZeroBased) which can be sparse and
causes mismatches with the lookup that uses params.StopSequence; instead compute
a trip-relative ordinal in the DB/query layer and return that same ordinal with
targetStopTime and totalStopsInTrip so request matching and response use the
same value. Update the call site that uses
GetTargetStopTimeWithTotalStopsBySequence(...) to request and receive a
trip-relative ordinal (not raw stop_sequence), stop using params.StopSequence
directly for lookup, and replace stopSequenceZeroBased, arrivalEnabled and
departureEnabled calculations to use the returned trip-relative ordinal and
totalStopsInTrip (reference symbols: GetTargetStopTimeWithTotalStopsBySequence,
params.StopSequence, targetStopTime, totalStopsInTrip, stopSequenceZeroBased,
arrivalEnabled, departureEnabled).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5e6ad429-2af9-4ee3-badc-d1d38685fff4

📥 Commits

Reviewing files that changed from the base of the PR and between 2f29632 and 64f5c18.

📒 Files selected for processing (6)
  • gtfsdb/block_layover_test.go
  • gtfsdb/stops_rtree.go
  • internal/models/arrival_and_departure.go
  • internal/models/current_time_test.go
  • internal/models/trip_details_test.go
  • internal/restapi/arrival_and_departure_for_stop_handler.go

Comment thread internal/restapi/arrival_and_departure_for_stop_handler.go Outdated
@3rabiii 3rabiii force-pushed the fix/arrival-departure-endpoint branch from 64f5c18 to b9228ce Compare May 18, 2026 17:08
@3rabiii 3rabiii force-pushed the fix/arrival-departure-endpoint branch from 1a091ea to 446d15b Compare May 23, 2026 16:43
@3rabiii 3rabiii marked this pull request as ready for review May 23, 2026 16:55
Copy link
Copy Markdown

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

🧹 Nitpick comments (3)
gtfsdb/query.sql (1)

1248-1249: ⚡ Quick win

Inconsistent parameter style: positional ?3 mixed with named @current_time.

Line 1248 uses @current_time but line 1249 uses the positional ?3. This happens to work because sqlc assigns @current_time to position 3, but it's fragile—if someone reorders the named parameters in the WHERE clause, ?3 could silently refer to the wrong parameter.

♻️ Proposed fix: use consistent named parameter
 WHERE st.trip_id = `@trip_id` AND st.stop_id = `@stop_id` AND CAST(`@current_time` AS INTEGER) IS NOT NULL
-ORDER BY ABS(st.arrival_time - CAST(?3 AS INTEGER)), st.stop_sequence
+ORDER BY ABS(st.arrival_time - CAST(`@current_time` AS INTEGER)), st.stop_sequence
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gtfsdb/query.sql` around lines 1248 - 1249, The ORDER BY mixes positional
parameter ?3 with the named parameter `@current_time` (used in the WHERE), which
is fragile; change the ORDER BY to use the same named parameter (`@current_time`)
instead of ?3 so the query consistently references CAST(`@current_time` AS
INTEGER) in the expression ABS(st.arrival_time - CAST(`@current_time` AS
INTEGER)), leaving the WHERE clause (st.trip_id = `@trip_id` AND st.stop_id =
`@stop_id` AND CAST(`@current_time` AS INTEGER) IS NOT NULL), and preserving ORDER
BY st.stop_sequence.
internal/restapi/block_sequence_helper.go (1)

35-38: 💤 Low value

Consider caching stop times to avoid redundant DB query.

The first loop (lines 35-38) fetches stop times for each block trip to compute startTime, and the second loop (lines 61-64) fetches them again for the matching trip. Since TripWithDetails only stores TripID and StartTime, this results in a redundant DB call for the matched trip.

Consider storing stopTimes in TripWithDetails to reuse them in the second loop.

♻️ Suggested refactor
 type TripWithDetails struct {
     TripID    string
     StartTime int
+    StopTimes []gtfsdb.StopTime
 }
 
 // ... in first loop ...
 if startTime != math.MaxInt64 {
     activeTrips = append(activeTrips, TripWithDetails{
         TripID:    blockTrip.ID,
         StartTime: int(startTime),
+        StopTimes: stopTimes,
     })
 }
 
 // ... in second loop, use trip.StopTimes instead of fetching again ...
 if trip.TripID == tripID {
-    stopTimes, err := api.GtfsManager.GtfsDB.Queries.GetStopTimesForTrip(ctx, trip.TripID)
-    if err != nil {
-        continue
-    }
-    for i, st := range stopTimes {
+    for i, st := range trip.StopTimes {
         if int(st.StopSequence) == stopSequence {
             return blockSequence + i
         }
     }
     return blockSequence
 }
-blockSequence += len(stopTimes)
+blockSequence += len(trip.StopTimes)

Also applies to: 61-64

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/restapi/block_sequence_helper.go` around lines 35 - 38, The code
repeatedly calls GetStopTimesForTrip for the same trip; modify TripWithDetails
to include a stopTimes field (or pointer) and when you fetch stopTimes the first
time (inside the loop using blockTrip.ID) store them on the TripWithDetails
instance; then in the later loop that currently re-fetches stop times (the
second loop around the matching trip logic) reuse TripWithDetails.stopTimes
instead of calling GetStopTimesForTrip again, and guard against nil/empty before
computing StartTime/other derived values.
internal/restapi/arrival_and_departure_for_stop_handler.go (1)

436-440: 💤 Low value

Inconsistent numberOfStopsAway default between handlers.

The singular handler defaults numberOfStopsAway to 0 when the lookup returns nil (line 439), but the plural handler (arrivals_and_departures_for_stop_handler.go, line 371) defaults to -1. This may cause inconsistent API responses depending on which endpoint is called.

If this is intentional per the API spec, please add a comment explaining the rationale. Otherwise, consider aligning the default value.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/restapi/arrival_and_departure_for_stop_handler.go` around lines 436
- 440, The singular handler in
internal/restapi/arrival_and_departure_for_stop_handler.go sets
numberOfStopsAway to 0 when numberOfStopsAwayPtr is nil while the plural handler
in arrivals_and_departures_for_stop_handler.go uses -1, causing inconsistent API
responses; either (A) make the singular handler use the same default (-1) as the
plural handler by changing the nil branch for numberOfStopsAway to -1 so both
handlers are aligned, or (B) if the difference is intentional per the API spec,
add a concise inline comment next to the nil-handling branch in
arrival_and_departure_for_stop_handler.go referencing the spec and explaining
why 0 differs from the plural handler (include the same comment in
arrivals_and_departures_for_stop_handler.go if needed for clarity).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/restapi/arrival_and_departure_for_stop_handler.go`:
- Around line 823-850: The getNumberOfStopsAway logic must treat a missing block
sequence explicitly because getBlockSequenceForStopSequence can return 0 for
“not found”; update getNumberOfStopsAway to detect a missing targetGlobalSeq
(e.g., if targetGlobalSeq == 0) and return nil immediately instead of computing
deltas that can be misleading, and adjust downstream checks similarly when
calling getBlockSequenceForStopID (or alter getBlockSequenceForStopSequence to
return a clear sentinel like -1 on not-found and handle that sentinel here);
modify the code paths in getNumberOfStopsAway (references: getNumberOfStopsAway,
getBlockSequenceForStopSequence, getBlockSequenceForStopID,
rawSequenceToOrdinal) so missing sequences lead to nil rather than producing
negative/incorrect numberOfStopsAway.

---

Nitpick comments:
In `@gtfsdb/query.sql`:
- Around line 1248-1249: The ORDER BY mixes positional parameter ?3 with the
named parameter `@current_time` (used in the WHERE), which is fragile; change the
ORDER BY to use the same named parameter (`@current_time`) instead of ?3 so the
query consistently references CAST(`@current_time` AS INTEGER) in the expression
ABS(st.arrival_time - CAST(`@current_time` AS INTEGER)), leaving the WHERE clause
(st.trip_id = `@trip_id` AND st.stop_id = `@stop_id` AND CAST(`@current_time` AS
INTEGER) IS NOT NULL), and preserving ORDER BY st.stop_sequence.

In `@internal/restapi/arrival_and_departure_for_stop_handler.go`:
- Around line 436-440: The singular handler in
internal/restapi/arrival_and_departure_for_stop_handler.go sets
numberOfStopsAway to 0 when numberOfStopsAwayPtr is nil while the plural handler
in arrivals_and_departures_for_stop_handler.go uses -1, causing inconsistent API
responses; either (A) make the singular handler use the same default (-1) as the
plural handler by changing the nil branch for numberOfStopsAway to -1 so both
handlers are aligned, or (B) if the difference is intentional per the API spec,
add a concise inline comment next to the nil-handling branch in
arrival_and_departure_for_stop_handler.go referencing the spec and explaining
why 0 differs from the plural handler (include the same comment in
arrivals_and_departures_for_stop_handler.go if needed for clarity).

In `@internal/restapi/block_sequence_helper.go`:
- Around line 35-38: The code repeatedly calls GetStopTimesForTrip for the same
trip; modify TripWithDetails to include a stopTimes field (or pointer) and when
you fetch stopTimes the first time (inside the loop using blockTrip.ID) store
them on the TripWithDetails instance; then in the later loop that currently
re-fetches stop times (the second loop around the matching trip logic) reuse
TripWithDetails.stopTimes instead of calling GetStopTimesForTrip again, and
guard against nil/empty before computing StartTime/other derived values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a474d4ca-6b2e-40eb-bb98-9ce086a68f64

📥 Commits

Reviewing files that changed from the base of the PR and between 64f5c18 and 3f4dc8a.

📒 Files selected for processing (15)
  • gtfsdb/block_layover_test.go
  • gtfsdb/query.sql
  • gtfsdb/query.sql.go
  • gtfsdb/stops_rtree.go
  • internal/models/arrival_and_departure.go
  • internal/models/current_time_test.go
  • internal/models/trip_details.go
  • internal/models/trip_details_test.go
  • internal/restapi/arrival_and_departure_for_stop_handler.go
  • internal/restapi/arrival_and_departure_for_stop_handler_test.go
  • internal/restapi/arrivals_and_departures_for_stop_handler.go
  • internal/restapi/block_sequence_helper.go
  • internal/restapi/calculate_block_trip_sequence_test.go
  • internal/restapi/trips_helper.go
  • internal/restapi/trips_helper_test.go
✅ Files skipped from review due to trivial changes (1)
  • gtfsdb/stops_rtree.go

Comment thread internal/restapi/arrival_and_departure_for_stop_handler.go
Copy link
Copy Markdown

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/restapi/arrival_and_departure_for_stop_handler.go (1)

842-847: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fallback path missing sentinel checks for -1 return values.

The change at line 835 correctly guards against -1 sentinels from getBlockSequenceForStopID, but the fallback path at lines 844-846 doesn't apply the same guard. If targetGlobalSeq == -1 (which we know is possible since line 835 checks for it) or vehicleGlobalSeq == -1, the computed numberOfStopsAway will be incorrect (e.g., -1 - 5 = -6 or 10 - (-1) = 11).

🐛 Proposed fix to add sentinel checks in fallback path
 	currentVehicleStopSequence := getCurrentVehicleStopSequence(vehicle)
 	if currentVehicleStopSequence != nil {
 		vehicleGlobalSeq := api.getBlockSequenceForStopSequence(ctx, activeTripID, *currentVehicleStopSequence, serviceDate)
+		if vehicleGlobalSeq == -1 || targetGlobalSeq == -1 {
+			return nil
+		}
 		numberOfStopsAway := targetGlobalSeq - vehicleGlobalSeq
 		return &numberOfStopsAway
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/restapi/arrival_and_departure_for_stop_handler.go` around lines 842
- 847, The fallback path computes numberOfStopsAway using
api.getBlockSequenceForStopSequence and getCurrentVehicleStopSequence but omits
sentinel checks; update the block where currentVehicleStopSequence is used
(calls to getCurrentVehicleStopSequence and api.getBlockSequenceForStopSequence)
to verify that both targetGlobalSeq and vehicleGlobalSeq are not -1 before
computing numberOfStopsAway and returning a pointer; if either is -1, return nil
(same behavior as the guarded path), ensuring you reference targetGlobalSeq,
vehicleGlobalSeq, getCurrentVehicleStopSequence,
api.getBlockSequenceForStopSequence, and numberOfStopsAway when making the
checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/restapi/block_sequence_helper.go`:
- Line 19: Don't return -1 from the error branch of GetTripsByBlockID; instead
preserve the recoverable fallback path by handling the error (log or wrap it)
and proceeding to the existing raw trip-level fallback function (the code that
handles trip-level lookup already present in this file). Replace the early
return in the GetTripsByBlockID error case with a call into the raw trip-level
fallback logic (or a call to the trip-level lookup helper used elsewhere in
block_sequence_helper.go) so transient block lookup failures fall back to
trip-level resolution rather than terminating with -1.

---

Outside diff comments:
In `@internal/restapi/arrival_and_departure_for_stop_handler.go`:
- Around line 842-847: The fallback path computes numberOfStopsAway using
api.getBlockSequenceForStopSequence and getCurrentVehicleStopSequence but omits
sentinel checks; update the block where currentVehicleStopSequence is used
(calls to getCurrentVehicleStopSequence and api.getBlockSequenceForStopSequence)
to verify that both targetGlobalSeq and vehicleGlobalSeq are not -1 before
computing numberOfStopsAway and returning a pointer; if either is -1, return nil
(same behavior as the guarded path), ensuring you reference targetGlobalSeq,
vehicleGlobalSeq, getCurrentVehicleStopSequence,
api.getBlockSequenceForStopSequence, and numberOfStopsAway when making the
checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 80118235-04c3-4639-a5d9-35d38799e23d

📥 Commits

Reviewing files that changed from the base of the PR and between 3f4dc8a and 944bd9e.

📒 Files selected for processing (2)
  • internal/restapi/arrival_and_departure_for_stop_handler.go
  • internal/restapi/block_sequence_helper.go

Comment thread internal/restapi/block_sequence_helper.go Outdated
@3rabiii 3rabiii force-pushed the fix/arrival-departure-endpoint branch from 944bd9e to 6ca0ece Compare May 23, 2026 19:42
Copy link
Copy Markdown

@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.

♻️ Duplicate comments (1)
internal/restapi/arrival_and_departure_for_stop_handler.go (1)

823-846: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Guard the fallback path from unresolved block sequence values.

Line 845 can still compute numberOfStopsAway when either sequence is -1, which returns misleading values instead of nil.

Suggested fix
 	currentVehicleStopSequence := getCurrentVehicleStopSequence(vehicle)
 	if currentVehicleStopSequence != nil {
 		vehicleGlobalSeq := api.getBlockSequenceForStopSequence(ctx, activeTripID, *currentVehicleStopSequence, serviceDate)
-		numberOfStopsAway := targetGlobalSeq - vehicleGlobalSeq
-		return &numberOfStopsAway
+		if targetGlobalSeq != -1 && vehicleGlobalSeq != -1 {
+			numberOfStopsAway := targetGlobalSeq - vehicleGlobalSeq
+			return &numberOfStopsAway
+		}
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/restapi/arrival_and_departure_for_stop_handler.go` around lines 823
- 846, In getNumberOfStopsAway, the fallback branch computes numberOfStopsAway
even when getBlockSequenceForStopSequence returns -1 for targetGlobalSeq or
vehicleGlobalSeq; update the fallback path in getNumberOfStopsAway to first
check if targetGlobalSeq == -1 or vehicleGlobalSeq == -1 and return nil in that
case, otherwise compute numberOfStopsAway = targetGlobalSeq - vehicleGlobalSeq
and return its pointer; reference functions/values: getNumberOfStopsAway,
getBlockSequenceForStopSequence, targetGlobalSeq, vehicleGlobalSeq,
getCurrentVehicleStopSequence.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@internal/restapi/arrival_and_departure_for_stop_handler.go`:
- Around line 823-846: In getNumberOfStopsAway, the fallback branch computes
numberOfStopsAway even when getBlockSequenceForStopSequence returns -1 for
targetGlobalSeq or vehicleGlobalSeq; update the fallback path in
getNumberOfStopsAway to first check if targetGlobalSeq == -1 or vehicleGlobalSeq
== -1 and return nil in that case, otherwise compute numberOfStopsAway =
targetGlobalSeq - vehicleGlobalSeq and return its pointer; reference
functions/values: getNumberOfStopsAway, getBlockSequenceForStopSequence,
targetGlobalSeq, vehicleGlobalSeq, getCurrentVehicleStopSequence.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: aff60daf-bbe0-42c9-a9e0-d6dee3a95f73

📥 Commits

Reviewing files that changed from the base of the PR and between 944bd9e and 6ca0ece.

📒 Files selected for processing (2)
  • internal/restapi/arrival_and_departure_for_stop_handler.go
  • internal/restapi/block_sequence_helper.go

@3rabiii
Copy link
Copy Markdown
Contributor Author

3rabiii commented May 23, 2026

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

✅ Actions performed

Full review triggered.

@3rabiii 3rabiii force-pushed the fix/arrival-departure-endpoint branch from 6ca0ece to de044be Compare May 23, 2026 20:51
@sonarqubecloud
Copy link
Copy Markdown

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant