Skip to content

feat: Implement arrivals-and-departures-for-location endpoint#787

Open
ARCoder181105 wants to merge 4 commits intoOneBusAway:mainfrom
ARCoder181105:feature/arrivals-departures-for-location
Open

feat: Implement arrivals-and-departures-for-location endpoint#787
ARCoder181105 wants to merge 4 commits intoOneBusAway:mainfrom
ARCoder181105:feature/arrivals-departures-for-location

Conversation

@ARCoder181105
Copy link
Copy Markdown
Contributor

@ARCoder181105 ARCoder181105 commented Mar 25, 2026

Overview
This PR ports the arrivals-and-departures-for-location endpoint from the legacy Java codebase into the Go maglev architecture. This endpoint allows clients to retrieve active arrivals and departures for multiple stops within a specified geographic bounding box or radius.

Key Features

  • Geospatial Querying: Utilizes the in-memory R-tree index to efficiently locate stops within the requested coordinate boundaries.
  • Overnight Trip Support: Queries active stop times across a 3-day window (yesterday, today, tomorrow) to ensure accurate scheduling for late-night routes.
  • Separated References: Aggregates Agencies, Routes, Stops, Trips, and Situations into a deduplicated references block to strictly adhere to the legacy JSON schema and optimize payload size.
  • Nearby Stops: Calculates haversine distance for nearbyStopIds to identify and include stops within the radius that may not currently have active arrivals.

Bug Fixes

  • Trip Status Fix: Resolved an existing issue in arrivals_and_departure_for_stop.go where the vehicle parameter was incorrectly passed as nil to BuildTripStatus.

Testing

  • Added table-driven tests for comprehensive parameter validation (radius, spans, minute offsets, timestamps).
  • Implemented end-to-end integration tests verifying payload structure and maximum record counts.
  • Validated context cancellation and timeout handling under load.

fix #799

@ARCoder181105 ARCoder181105 changed the title Feature/arrivals departures for location feat: implement arrivals-and-departures-for-location endpoint Mar 25, 2026
@ARCoder181105 ARCoder181105 changed the title feat: implement arrivals-and-departures-for-location endpoint feat: Implement arrivals-and-departures-for-location endpoint Mar 27, 2026
@ARCoder181105 ARCoder181105 marked this pull request as ready for review March 27, 2026 15:54
@ARCoder181105
Copy link
Copy Markdown
Contributor Author

Hi @aaronbrethorst,

I've ported the arrivals-and-departures-for-location endpoint and achieved strict schema parity with the Java implementation. I was able to map almost all of the fields successfully.

A few technical notes and questions for your review:

  • JSON Output Improvement (Bug Fix): I noticed the legacy Java output dumps massive amounts of duplicate IDs into the entry.stopIds array. I fixed this in the Go implementation by using a map to ensure the returned stopIds array is properly deduplicated.
  • N+1 Query Avoidance: I structured the GTFS DB calls to batch-fetch agencies, routes, and trips outside the main loops to keep the endpoint latency low.
  • Sorting Logic: I intentionally did not port the primarySortAgency sorting logic from Java's BeanFactoryV2. It looked like a Spring-injected customization specific to Sound Transit, so I left the Go references unsorted to match our other Maglev endpoints.
  • Realtime Testing Blocker: I had some trouble fully comparing the realtime GTFS-RT output because my local Java Docker container is failing to configure/run with the realtime data streams. The static schedule parity is completely verified, however.

Finally, I know some of my inline code comments might be a bit vague. I wrote them based on my current understanding of the pipeline, but I would really appreciate your suggestions on how I can improve the documentation for future maintainers.

Let me know what you think!

@ARCoder181105
Copy link
Copy Markdown
Contributor Author

Also I know the commits are also a bit vague once these changes approves I will squash and rebase the branch into single atomic commit...

@ARCoder181105
Copy link
Copy Markdown
Contributor Author

Note: arrivalEnabled and departureEnabled are currently hardcoded to true. To make these strictly match the
GTFS schedule, we will need to update the GetStopTimesForStopInWindow SQL query to explicitly select the pickup_type and drop_off_type columns. I plan to do this in a quick follow-up PR so this one stays focused on the core handler logic.

@ARCoder181105 ARCoder181105 marked this pull request as draft March 28, 2026 03:30
@ARCoder181105 ARCoder181105 marked this pull request as ready for review March 28, 2026 04:40
Port Java arrivals-and-departures-for-location to Go maglev architecture.

- Geospatial stop lookup via in-memory R-tree index
- 3-day window queries (yesterday/today/tomorrow) for overnight trip support
- Batch-fetch routes/trips/stop-times to avoid N+1 queries
- Deduplicated references block (Agencies, Routes, Stops, Trips, Situations)
- nearbyStopIds via haversine distance, excluding stops already in stopIds
- arrivalStatus derived from schedule deviation (LATE/EARLY/ON_TIME/default)
- limitExceeded flag honoring maxCount (mirrors Java MaxCountSupport)
- Add StopWithDistance model and NewArrivalsAndDeparturesForLocationResponse
- Add ORDER BY to GetAgenciesForStops for deterministic results
- Fix nil vehicle passed to BuildTripStatus in arrivals_and_departure_for_stop.go
- Register GET /api/where/arrivals-and-departures-for-location.json
- Add unit, E2E, and context cancellation tests

Closes OneBusAway#787
Fixes OneBusAway#799
@ARCoder181105 ARCoder181105 force-pushed the feature/arrivals-departures-for-location branch from e3c9b4d to b056442 Compare March 28, 2026 11:01
@3rabiii
Copy link
Copy Markdown
Contributor

3rabiii commented Mar 28, 2026

Hey @ARCoder181105 Great work on this endpoint!
While reviewing the legacy Java documentation and code (ArrivalsAndDeparturesForLocationAction) for API parity, I noticed that this endpoint should also accept a few more optional parameters:
1.routeType: an optional comma-delimited list of GTFS routeTypes to filter by.
2.emptyReturnsNotFound: a boolean flag to indicate if an empty result should return a 404 instead of a 200.
I see we are parsing latSpan, lonSpan, time, etc., but it seems these might have been missed in the ArrivalsAndDeparturesForLocationParams struct.

…dpoint

- Add parsing and handling for emptyReturnsNotFound parameter
- Add parsing and GTFS filtering for routeType parameter
- Add frequencyMinutesBefore and frequencyMinutesAfter parsing
- Fix nearbyStopIds logic to match Java's includeInputIdsInNearby=true override
@ARCoder181105
Copy link
Copy Markdown
Contributor Author

Hi @3rabiii, thanks for the review!

I have implemented the missing parameters you mentioned (routeType and emptyReturnsNotFound which now properly returns a 404).

I also addressed a few other minor parity gaps (added frequencyMinutesBefore and fixed the nearbyStopIds logic to match the Java setIncludeInputIdsInNearby(true) override).

Everything has been tested and verified against the live PugetSound schema. Ready for another look whenever you have time!

@ARCoder181105
Copy link
Copy Markdown
Contributor Author

Hi @aaronbrethorst , @Ahmedhossamdev

The PR is ready for review ...

@Ahmedhossamdev
Copy link
Copy Markdown
Member

Hi @ARCoder181105
Can you update the openapi now? I have added the new endpoint to our openapi.yml file

@3rabiii
Copy link
Copy Markdown
Contributor

3rabiii commented Mar 29, 2026

@Ahmedhossamdev I already updated it here #807

@ARCoder181105
Copy link
Copy Markdown
Contributor Author

ARCoder181105 commented Mar 29, 2026

Already done by @3rabiii , PR #807

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.

Implement arrivals-and-departures-for-location endpoint

3 participants