remove non-spec outOfRange field from trips-for-route - #1236
Conversation
|
Note Reviews pausedUse the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe trips-for-route handler now constructs list responses without range metadata. Tests verify that ChangesTrips-for-route response shape
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
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. Comment |
Code reviewFound 1 issue:
maglev/internal/restapi/trips_for_route_handler.go Lines 33 to 37 in 71b8760 Otherwise this looks right: the wiki spec for 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
aaronbrethorst
left a comment
There was a problem hiding this comment.
The premise is right and I checked it independently. outOfRange appears nowhere in the authoritative trips-for-route spec — the response schema lists limitExceeded, list, and references and nothing else — and testdata/openapi.yml agrees: the 200 schema for /api/where/trips-for-route/{routeID}.json defines exactly those three keys. Meanwhile trips-for-location, stops-for-location, routes-for-location, search/stop, and search/route all legitimately declare outOfRange, several as required. So removing it from this endpoint only is correct, and leaving OutOfRange on the shared ListData struct is also correct since those other endpoints decode through it.
I also like that you asserted key absence on the raw JSON via fetchRawData rather than through a typed struct — a typed decode can't tell "absent" from "false", so this is the only way the test actually proves anything.
One problem, and it's specifically a hazard of resolving this PR's merge conflict.
There's a third call site on main that this PR doesn't convert.
Your branch's merge base predates commit a678600 ("Return empty list for unknown route IDs"), which added another models.NewListResponseWithRange(...) to this handler for the unknown-agency path. Current main has three:
38: response := models.NewListResponseWithRange([]models.TripsForRouteListEntry{}, *references, false, api.Clock, false)
198: response := models.NewListResponseWithRange([]models.TripsForRouteListEntry{}, references, false, api.Clock, false)
468: response := models.NewListResponseWithRange(result, references, false, api.Clock, false)
The PR converts the two that existed on its base (the empty-list and success paths). Line 38 is new, and git won't flag it as a conflict — it's in a region your diff doesn't touch. So a straightforward conflict resolution leaves the unknown-route-ID path still emitting outOfRange, and the endpoint stays off-spec for exactly the case where a client is most likely to be poking at it.
Please rebase onto main and convert that one too. While you're there, it'd be worth extending TestTripsForRouteHandler_OutOfRangeNotEmitted to cover the empty-list and unknown-agency responses as well — right now only the populated success path is checked for key absence, which is how the third site slipped through in the first place. A small table over the three response paths would make this robust against the next handler that gets added.
For the record on provenance: I traced the field's origin and there's no spec-driven rationale to preserve. It arrived with the handler's initial implementation in 8ebd4f73 and got copy-pasted into new branches from there. No client requirement, no earlier spec reading. So this is a clean removal, not a behavior we're knowingly dropping.
Rebase, convert the third call site, broaden the test, and I'll merge it.
Replace NewListResponseWithRange with NewListResponse in the trips-for-route handler to ensure the response envelope matches the API specification. The outOfRange field is not defined in the spec for this endpoint. By swapping the response builder, the key is omitted from the JSON envelope while maintaining the shared ListData struct for safely deserializing other location-based endpoints. Added raw JSON tests to verify absolute compliance.
71b8760 to
e1751ac
Compare
|
@CodeRabbit pause |
✅ Action performedReviews paused. |
|
OBA API Review: working tree (branch
|
| Behaviour | Wayfinder/SDK | iOS | Android |
|---|---|---|---|
data.outOfRange no longer emitted on trips-for-route responses |
none | none | none |
- JS SDK/Wayfinder:
TripsForRouteListResponse.Datanever declaredoutOfRange; no component reads it off this endpoint's response. - iOS: doesn't call
trips-for-routeat all. Separately,outOfRangeis decoded generically (optional,decodeIfPresent) on the sharedRESTAPIResponse<T>and has no downstream reader anywhere in the codebase — dead property regardless. - Android:
ListWithReferences.outOfRangedefaults tofalsevia kotlinx.serialization when the key is missing — identical to what it always deserialized to before (spec confirms this field was alwaysfalsefor this endpoint, a documented Java-parity artifact). The only real consumer of.outOfRange(MapDataSource.kt) reads it from a different call (stopsForLocation); the actual trips-for-route adapter (asRouteTrips()) never touches it.
Spec check
Overall: spec-consistent
outOfRangeremoval matches the spec'sdataschema exactly.- Extended the check to the rest of the handler for drift beyond this PR's scope:
maxCount(correctly unimplemented, matching the spec's Implementation Decisions entry),includeTrip/includeStatus/includeSchedule/includeReferencesdefaults (all correctly defaulttrue),data.limitExceeded(correctly hardcodedfalse, matching the documented Suspected Defect this PR doesn't touch), anddata.list[]field shape (matches spec, includingomitemptyschedule/status). No new deviations found; no Implementation Decisions entry needed.
Summary
This is a clean, minimal, single-purpose fix: it closes issue #1234 exactly as scoped, with no client-visible regressions across Wayfinder/JS-SDK, iOS, or Android, and no spec drift elsewhere in the handler. Test coverage is precise and reuses existing helpers rather than hand-rolling new plumbing.
Comments have been addressed



Description
This PR fixes a compliance issue where the
trips-for-routeendpoint was emitting an undocumentedoutOfRangefield in its responsedataenvelope.The API specification explicitly requires the
dataobject to only containlimitExceeded,list, andreferences. The discrepancy was caused by usingmodels.NewListResponseWithRangeinstead of the standardmodels.NewListResponse.Changes Made
models.NewListResponseWithRangetomodels.NewListResponseininternal/restapi/trips_for_route_handler.go(for both the early return and main response paths).TestTripsForRouteHandler_OutOfRangeNotEmittedto fetch the raw JSON response as amap[string]any."outOfRange"key is completely absent from the JSON payload."limitExceeded","list", and"references"remain present.OutOfRangeboolean ininternal/restapi/response_types.go(ListDatastruct) to avoid breaking deserialization for other location-based endpoints (likestops-for-location) that legally share this struct.Closes: #1234
Summary by CodeRabbit
outOfRangefield when it is not applicable.