Skip to content

Build stops-for-agency records with shared code - #1809

Closed
aaronbrethorst wants to merge 2 commits into
ab/shapeless-positionsfrom
ab/stops-for-agency-shared
Closed

aaronbrethorst wants to merge 2 commits into
ab/shapeless-positionsfrom
ab/stops-for-agency-shared

Conversation

@aaronbrethorst

@aaronbrethorst aaronbrethorst commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

Stacked on #1807. Part of the stop consolidation work (#1771–#1779). No issue filed yet.

What it does

stops-for-agency now builds its stop records, parent stations and route references with the shared stop builder. It was the last endpoint with its own copy of that code, so every stop record in Maglev now comes from one place (29 lines added, 106 removed).

Root cause

buildStopsListForAgency hand-built models.Stop values:

  • it copied stops.direction as is;
  • it listed routes in database order;
  • it used buildParentStationReferences and BuildRouteReferences for the references.

Now the stops come from stopModelsByIDs and the parent stations from missingParentStops, together with their route rows. Route references come from routeReferencesForStops, as block does since #1798. The two helpers are deleted; BuildRouteReferences stays for its other callers.

Testing

  • Test failing before this change: TestStopsForAgency_UsesSharedStopRecords, which requires the list to equal the shared builder's records for the agency's stops. On RABA it failed on route order: for stop 25_1001, before ["25_159","25_160","25_157"], after ["25_157","25_159","25_160"].
  • Existing tests: the cross-agency route owner test, the parent-station tests and OpenAPI conformance all pass. Conformance caught references.stops serializing as null when there are no parent stations; that's fixed.

Response comparison

Production Puget Sound returns 404 for stops-for-agency, so there's no Java response to compare against. On the synthetic parity feed, stops-for-agency/40 and /1 still match Java's IDs.

Checklist

  • This PR addresses one issue.
  • It is under ~200 changed lines, or the description says why it can't be split.
  • This PR is not a bug fix, or the new or changed test fails on main and passes on this branch.
  • Each commit is one logical change with a clear message.
  • I did not hand-edit sqlc-generated files under gtfsdb/ (db.go, models.go, query.sql.go) or testdata/openapi.yml (synced from upstream).
  • This PR changes no handler, or handlers pass r.Context() to DB/service calls, not context.Background().
  • The response comparison above is filled in, or this PR doesn't change a Java-served response.
  • This PR adds no endpoint, or each new endpoint matches testdata/openapi.yml, has an issue open on OneBusAway/sdk-config, or is outside the SDK and the description says why.
  • I read every line of this diff and can explain it if asked.

Notes for reviewers

  • Direction: this now goes through DirectionCalculator, as on every other endpoint. That costs little: directions are computed at import and stored in stops.direction, which the calculator reads first. The visible change is that a feed value like North becomes N, matching other endpoints. RABA's directions are unchanged.
  • Order: the list follows GetStopIDsForAgency order instead of GetStopsByIDs order.

After review

  • routeReferencesForStops built its list from a map, so references.routes changed order on every request here and in block. It now sorts by route ID.
  • stopsAndParentStations is now shared with BuildStopReferencesAndRouteIDsForStops, instead of being repeated here.
  • The test also pins stop 25_1001's route order and direction, so it no longer only compares the handler with the builder it calls.

@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: ca91c205-514b-412d-a8b1-347832e26062

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@github-actions

Copy link
Copy Markdown

@aaronbrethorst, the PR description does not follow the PR template:

  • No linked issue. Add Fixes #N (or Part of #N) for a triaged issue.
  • Testing: "Test failing on main before this change:" is empty.
  • Testing: "Manual check:" is empty.
  • Response comparison: "Request URL(s):" is empty.
  • Response comparison: "Java server, feeds and date checked:" is empty.
  • Response comparison: "Maglev before:" is empty.
  • Response comparison: "Maglev after:" is empty.
  • Response comparison: "Java:" is empty.
  • Checklist item is not checked: "I read every line of this diff and can explain it if asked." If this item doesn't apply to your PR, ask a maintainer.

Keep this PR as Draft until these are fixed. This comment updates when the description changes.

@github-actions

Copy link
Copy Markdown

Performance Smoke Test Results

Status: PASSED

Metric Value
p(95) latency 2.2 ms
Error rate 0.00%
Total requests 343
Req/sec 11.3

Smoke test config: 5 VUs x 30s. Thresholds: p(95) < 300ms, error rate < 1%.

Full results uploaded as workflow artifact: k6-smoke-summary.

stops-for-agency was the last endpoint with its own copy of the stop
record code. It copied the stops.direction column as is, listed each
stop's routes in database order, and found parent stations and route
references through two more helpers of its own.

Take the stops, their parent stations and their routes from
stopModelsByIDs and missingParentStops, and build route references
with routeReferencesForStops, as block does. A stop's direction now
goes through DirectionCalculator, which reads the same column first
and turns a feed value like "North" into "N". Its routeIds follow the
shared builder's route-name order.
routeReferencesForStops built its list from a map, so references.routes
came back in a different order on every request for stops-for-agency
and block, where the old stops-for-agency code sorted by route ID.
Sort by ID.

stops-for-agency repeated BuildStopReferencesAndRouteIDsForStops line
for line to keep parent stations apart from the stops. Both now use
stopsAndParentStations. The stops-for-agency test also pins one stop's
route order and direction, so it no longer only compares the handler
with the builder it calls.
@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

Performance Smoke Test Results

Status: PASSED

Metric Value
p(95) latency 2.1 ms
Error rate 0.00%
Total requests 331
Req/sec 10.9

Smoke test config: 5 VUs x 30s. Thresholds: p(95) < 300ms, error rate < 1%.

Full results uploaded as workflow artifact: k6-smoke-summary.

@github-actions

Copy link
Copy Markdown

Performance Smoke Test Results

Status: PASSED

Metric Value
p(95) latency 2.3 ms
Error rate 0.00%
Total requests 340
Req/sec 11.2

Smoke test config: 5 VUs x 30s. Thresholds: p(95) < 300ms, error rate < 1%.

Full results uploaded as workflow artifact: k6-smoke-summary.

@aaronbrethorst

Copy link
Copy Markdown
Member Author

Closing as superseded. The multi-feed static GTFS spec (#1811, docs/multi-agency-static-feeds-spec.md §10) folds this stack's stop-ID rules into the per-feed default agency and the stored-ID identity model; they return as phases B and C of that plan. The Java-recorded data in testdata/java_parity and the tests on this branch will be reused there. #1806, #1807 and #1810 are not identity work and stay open to be re-cut against main.

@aaronbrethorst
aaronbrethorst deleted the ab/stops-for-agency-shared branch November 8, 2026 18:31
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