-
Notifications
You must be signed in to change notification settings - Fork 20
feat: publish route_id and start_date in the driver-reported TripDescriptor #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7b6c680
31a0792
60093f9
dd1df70
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -201,7 +201,7 @@ The server produces a standard `FeedMessage` containing `VehiclePosition` entiti | |
| ```protobuf | ||
| vehicle { | ||
| trip { | ||
| trip_id: "route_5_0830" | ||
| trip_id: "t_5_0830" | ||
| route_id: "5" | ||
| start_time: "08:30:00" | ||
| start_date: "20260715" | ||
|
|
@@ -245,7 +245,9 @@ Each location report is a single point sent directly from the Android app as it | |
| ```json | ||
| { | ||
| "vehicle_id": "vehicle-042", | ||
| "trip_id": "route_5_0830", | ||
| "trip_id": "t_5_0830", | ||
| "route_id": "5", | ||
| "start_date": "20260715", | ||
| "latitude": -1.2921, | ||
| "longitude": 36.8219, | ||
| "bearing": 180.0, | ||
|
|
@@ -257,6 +259,8 @@ Each location report is a single point sent directly from the Android app as it | |
|
|
||
| The server updates its in-memory state with the latest position and persists the point to the database. Points older than a configurable staleness threshold (default 5 minutes) are excluded from the GTFS-RT feed. | ||
|
|
||
| > `trip_id`, `route_id` and `start_date` are all optional. `trip_id` is the GTFS `trip_id` and must be left empty when the driver only knows the route — never send a route id in `trip_id`. `route_id` is the GTFS `route_id`; when `trip_id` is empty it is the only thing a consumer can match on. `start_date` is the service date, `YYYYMMDD`, and is accepted only alongside `trip_id` or `route_id`. The feed's `TripDescriptor` carries exactly the fields that were sent, and is omitted entirely when both `trip_id` and `route_id` are empty. | ||
|
|
||
| **`POST /api/v1/locations` validation and error contract** | ||
|
|
||
| The ingest endpoint performs strict request validation before writing data: | ||
|
|
@@ -265,6 +269,7 @@ The ingest endpoint performs strict request validation before writing data: | |
| - The request body must contain exactly one JSON object. | ||
| - Unknown JSON fields are rejected. | ||
| - Standard payload validation still applies (`vehicle_id`, coordinates, timestamp). | ||
| - `trip_id` and `route_id` are capped at 100 characters; `start_date` must be a real `YYYYMMDD` date. | ||
|
|
||
| Response codes: | ||
|
|
||
|
|
@@ -278,7 +283,7 @@ Examples: | |
| # Valid request | ||
| curl -i -X POST http://localhost:8080/api/v1/locations \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"vehicle_id":"bus-1","trip_id":"route-5","latitude":-1.29,"longitude":36.82,"timestamp":1752566400}' | ||
| -d '{"vehicle_id":"bus-1","route_id":"5","latitude":-1.29,"longitude":36.82,"timestamp":1752566400}' | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Use a current timestamp in the valid request example.
🤖 Prompt for AI Agents |
||
|
|
||
| # Invalid content type -> 415 | ||
| curl -i -X POST http://localhost:8080/api/v1/locations \ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,7 @@ import ( | |
|
|
||
| type locationReport struct { | ||
| VehicleID string `json:"vehicle_id"` | ||
| RouteID string `json:"route_id"` | ||
| Latitude float64 `json:"latitude"` | ||
| Longitude float64 `json:"longitude"` | ||
| Bearing float64 `json:"bearing"` | ||
|
|
@@ -64,9 +65,10 @@ func main() { | |
| wg.Add(1) | ||
| vehicleID := fmt.Sprintf("sim-vehicle-%03d", i+1) | ||
| route := routes[i%len(routes)] | ||
| routeID := fmt.Sprintf("sim-route-%d", i%len(routes)+1) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- changed file context ---'
sed -n '1,140p' cmd/simulator/main.go
printf '%s\n' '--- simulator route definitions and send path ---'
sed -n '1,220p' cmd/simulator/routes.go
rg -n --glob '!vendor/**' 'route_id|routeID|GTFS|routes.txt|sim-route' .
printf '%s\n' '--- tracked GTFS-related files ---'
git ls-files | rg -i 'gtfs|route|simulator|development'Repository: OneBusAway/vehicle-positions Length of output: 50384 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- fixture route identifiers ---'
sed -n '115,135p' rider/fixture_test.go
printf '%s\n' '--- location report contract and handler path ---'
sed -n '1,120p' handlers.go
sed -n '140,220p' rider_handlers.go
printf '%s\n' '--- simulator tests around route_id ---'
sed -n '130,195p' cmd/simulator/main_test.go
printf '%s\n' '--- simulator design contract ---'
sed -n '315,340p' docs/superpowers/plans/2026-09-06-product-readiness.md
printf '%s\n' '--- development simulator usage ---'
sed -n '320,380p' docs/development.mdRepository: OneBusAway/vehicle-positions Length of output: 13197 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- route ID propagation into the GTFS-RT feed ---'
rg -n -C 5 'buildFeed|RouteID|RouteId' --glob '*.go' --glob '!**/*_test.go' .Repository: OneBusAway/vehicle-positions Length of output: 32831 Map simulator routes to GTFS route IDs. The simulator emits Add an explicit mapping from each simulator route to a valid GTFS 🤖 Prompt for AI Agents |
||
| go func() { | ||
| defer wg.Done() | ||
| simulateVehicle(ctx, client, *baseURL, vehicleID, route, *interval, s) | ||
| simulateVehicle(ctx, client, *baseURL, vehicleID, route, routeID, *interval, s) | ||
| }() | ||
| } | ||
| wg.Wait() | ||
|
|
@@ -80,7 +82,7 @@ func main() { | |
| log.Printf("simulation complete: %d requests, %d ok, %d failed, avg=%dms", ok+fail, ok, fail, avgMS) | ||
| } | ||
|
|
||
| func simulateVehicle(ctx context.Context, client *http.Client, baseURL, vehicleID string, route []Waypoint, interval time.Duration, s *stats) { | ||
| func simulateVehicle(ctx context.Context, client *http.Client, baseURL, vehicleID string, route []Waypoint, routeID string, interval time.Duration, s *stats) { | ||
| ticker := time.NewTicker(interval) | ||
| defer ticker.Stop() | ||
|
|
||
|
|
@@ -122,6 +124,7 @@ func simulateVehicle(ctx context.Context, client *http.Client, baseURL, vehicleI | |
|
|
||
| report := locationReport{ | ||
| VehicleID: vehicleID, | ||
| RouteID: routeID, | ||
| Latitude: pos.Lat, | ||
| Longitude: pos.Lon, | ||
| Bearing: brng, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Remove unsupported fields from the GTFS-RT feed example.
buildFeedemits onlytrip_id,route_id, andstart_datefor driver entities. The rider entity producer also does not emitstart_timeorschedule_relationship. Remove those fields from the example.🤖 Prompt for AI Agents