Repository navigation
feat(live): worldwide providers as data — 73 feeds, 14 countries, licence-checked - #195
Merged
Merged
Conversation
NateIsern
force-pushed
the
feat/live-renfe-ld
branch
from
October 13, 2026 00:05
d5d431b to
382f8b8
Compare
73 real-time feeds in 14 countries, each a `LiveProvider` entry (id, place, URL, coverage, credit, licence, auth, interval, static GTFS) built by one adapter per standard: GTFS-RT vehicle positions, GTFS-RT trip updates, GBFS and SIRI-VM (new, XML and JSON). 51 are keyless; 22 wait for a key the owner registers, and stay off until LIVE_SOURCE_<ID>_KEY is set. - Licence first: every source now carries `licenceCheck` (day, page, verbatim words allowing public commercial redistribution) and a keyed one its registration URL; licence.test.ts fails an entry without them, with a name or credit the contract refuses, or with a key in its URL. - LIVE_SOURCES=all takes the whole checked catalogue, skipping keyed sources without a key and those still `awaiting` a permission (adsb-lol, nyc-bikeshare, york-yrt) unless named beside it. - Modes come from each operator's routes.txt. Big archives are read by HTTP range (directory + routes.txt; the Netherlands' 259 MB file costs 236 KB), `only: 'routes' | 'trips'` skips shapes that would cost GBs, and a static GTFS unneeded for 15 minutes is let go. ZIP64 sizes are read. - A multimodal feed defaults to mode `other`, drawn as a neutral marker with no 3D body; a route id is shown as the line only where riders use it (fixes Renfe LD showing route ids too). - GTFS route types 1100-1199 are air services, not ferries; route ids are looked up as ids before short names; one Accept header every protobuf server answers (406 from Trapeze, JSON from Adelaide otherwise). docs/MAP_LIVE.md: coverage table, exclusions with reasons, keys to register. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NateIsern
force-pushed
the
feat/live-worldwide
branch
from
October 13, 2026 00:20
a710835 to
5dc2b6e
Compare
An error occurred while trying to automatically change base from
feat/live-renfe-ld
to
main
October 13, 2026 01:01
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #194 (Renfe regional/long-distance), which is stacked on #168 (production readiness). Merge those first. Don't merge before them.
What
There are now 73 real-time feeds in 14 countries. Each one is a data entry (
LiveProviderinpackages/backend/src/live/providers.ts) rather than per-city code. One adapter per standard builds them:adapters/gtfsRealtime.tsadapters/arrivalEstimates.tsadapters/gbfs.tsadapters/siriVm.ts(new)LIVE_SOURCE_<ID>_KEYis set. Where to register for each key is indocs/MAP_LIVE.mdunder "Keys to register".feeds_v2.csv) and from the operators' own portals.licenceCheck: the date, the page and the verbatim words that allow public commercial redistribution.licence.test.tsfails a source that:LIVE_SOURCES=alltakes the whole licence-checked catalogue. It skips:awaitinga permission (adsb-lol,nyc-bikeshare,york-yrt). Name one besideallonce its permission is in, e.g.all,adsb-lol.Correctness found along the way
routes.txt. A position names a route, not a mode, and Helsinki or Prague put every mode in one feed. Static GTFS is read at the depth each network can afford, measured with the hub's own parser:only: 'routes'oronly: 'trips'where shapes would cost GBs (Prague 2.2 GB, Helsinki 1.1 GB, Austin 1.7 GB resident while parsing);routes.txt. The Netherlands' 259 MB file costs 236 KB and Norway's 534 MB file 250 KB. Range requests sendaccept-encoding: identitybecause TransLink Queensland gzips on the fly and would otherwise range over its gzip stream.other. Such a vehicle is drawn as a neutral marker with no 3D body, never guessed into a bus (kinds.ts,points.ts).routeIdIsLine). Before,lineOf: () => nullfell back to the route id, which put ids like100001andOST:Line:1_400on the map. That includes feat(live): Renfe's regional and long-distance trains beside Rodalies #194's Renfe LD trains, fixed here.Acceptheader that every protobuf server answers. Trapeze servers (Edmonton, Halifax, Mississauga) returned 406 to the old one, and Adelaide returned JSON.Evidence
Every keyless entry was polled once through its own adapter on 2026-10-12 around 21:00 UTC. Counts are in the coverage table, e.g.:
End-to-end hub smoke with
LIVE_SOURCES=all(60 sources configured) and viewers in six cities:Lines and colours came from each operator's static file. The process was 97 MB resident.
Tests. Each fix's test was checked to fail without the fix:
licence.test.ts: every source's licence evidence, contract shapes, and no keys in URLs.providers.test.ts:Client-Identifier;allversusawaiting.siriVm.test.ts: XML and JSON.staticGtfs.test.ts: ZIP64, ranged reads (the whole archive is never fetched; falls back when the server ignores ranges), routes-only and trips-only depth, route ids before short names.hub.test.ts: ranged static read through the hub, unencoded, giving line and mode; static GTFS released after 15 minutes idle and re-read on return.combined.test.ts: route types, including air ≠ ferry.points.test.ts:otheris a neutral marker with no 3D body.Backend 1,197 pass with a real Valkey (
TEST_VALKEY_URL); SDK 207; frontend 1,639.bun run lint,bun run typecheck,check:openapiandcheck:contractsare clean.Owner actions (nothing here writes SSM or touches AWS)
LIVE_SOURCES=all(seedocs/MAP_LIVE.md→ Configuration). This is in place of feat(live): production — one poller across tasks, a fraction of the bytes, on by default #168's list. TheREDIS_URLand 2,048 MB memory changes from feat(live): production — one poller across tasks, a fraction of the bytes, on by default #168 still apply./oxy/goway/LIVE_SOURCE_<ID>_KEYin the task'ssecretsand the execution role'sssm:GetParameters:york-yrtbesideall.🤖 Generated with Claude Code