Defer V3-08/V3-09, add V3-17 to investigate self-hosted OSRM
Per request: V3-08's routing-engine direction is decided (self-hosted OSRM over a hosted API or the public demo instance) but standing one up is split into its own ticket, V3-17, since provisioning a server is different work from the app code that calls it. V3-08 and V3-09 are marked Deferred pending V3-17. V3-17 also names a real tension worth flagging rather than quietly ignoring: this backlog's own organizing principle is 'v3 is everything buildable with no server,' and a self-hosted OSRM instance is a server -- so V3-08/V3-09 sit oddly under docs/v3/ once V3-17 exists. Left unresolved by design (a documentation call for later), noted in both V3-17 and BACKLOG.md's v4 section rather than silently renumbering tickets that are already cross-referenced throughout the docs.
This commit is contained in:
@@ -252,6 +252,14 @@ Split out from v3 deliberately. These three are **one programme, not three items
|
|||||||
needs a server, an identity system, and a privacy stance, and none of them is worth
|
needs a server, an identity system, and a privacy stance, and none of them is worth
|
||||||
building alone. Nothing in v3 depends on any of them.
|
building alone. Nothing in v3 depends on any of them.
|
||||||
|
|
||||||
|
**A fourth item that doesn't fit that programme but shares its precondition:**
|
||||||
|
self-hosted road-snapped routing (v3's V3-08/V3-09, gated on
|
||||||
|
[V3-17](v3/V3-17-osrm-hosting.md)). It needs a server the same way this section's three
|
||||||
|
items do, but nothing about identity, privacy, or the group-ride use case — it's routing
|
||||||
|
infrastructure, not a rider-facing programme. Filed under `docs/v3/` for now since that's
|
||||||
|
where the tickets it unblocks already live; flagged here because "v3 is everything
|
||||||
|
buildable with no server" stops being strictly true the moment V3-17 is picked up.
|
||||||
|
|
||||||
## Live group rides
|
## Live group rides
|
||||||
|
|
||||||
Invite someone to a ride and see both of you on the map, live.
|
Invite someone to a ride and see both of you on the map, live.
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ backup are v4 — see [../BACKLOG.md](../BACKLOG.md).
|
|||||||
| [V3-05](V3-05-mounted-mode.md) | Mounted (handlebar) mode | M | V3-04 | Done |
|
| [V3-05](V3-05-mounted-mode.md) | Mounted (handlebar) mode | M | V3-04 | Done |
|
||||||
| [V3-06](V3-06-notification-stats.md) | Live stats in the notification | S | — | Done |
|
| [V3-06](V3-06-notification-stats.md) | Live stats in the notification | S | — | Done |
|
||||||
| [V3-07](V3-07-route-drawing.md) | Route drawing (pins, straight lines) | M | — | Done |
|
| [V3-07](V3-07-route-drawing.md) | Route drawing (pins, straight lines) | M | — | Done |
|
||||||
| [V3-08](V3-08-road-routing.md) | Road-snapped routing and ETA | L | V3-07, V3-01 | Not started |
|
| [V3-08](V3-08-road-routing.md) | Road-snapped routing and ETA | L | V3-07, V3-01, **V3-17** | Deferred (needs V3-17) |
|
||||||
| [V3-09](V3-09-route-following.md) | Follow a planned route | M | V3-04, V3-08 | Not started |
|
| [V3-09](V3-09-route-following.md) | Follow a planned route | M | V3-04, V3-08 | Deferred (needs V3-08) |
|
||||||
| [V3-10](V3-10-trip-splitting.md) | Trip splitting | S | — | Done |
|
| [V3-10](V3-10-trip-splitting.md) | Trip splitting | S | — | Done |
|
||||||
| [V3-11](V3-11-offline-tiles.md) | Offline tile pre-download | M | V3-04 | Partially done (pipeline shipped; needs aeroplane-mode device verification) |
|
| [V3-11](V3-11-offline-tiles.md) | Offline tile pre-download | M | V3-04 | Partially done (pipeline shipped; needs aeroplane-mode device verification) |
|
||||||
| [V3-12](V3-12-crash-reporting.md) | Crash reporting | S | — | Partially done (code only; needs a real Sentry DSN + release build) |
|
| [V3-12](V3-12-crash-reporting.md) | Crash reporting | S | — | Partially done (code only; needs a real Sentry DSN + release build) |
|
||||||
@@ -33,6 +33,7 @@ backup are v4 — see [../BACKLOG.md](../BACKLOG.md).
|
|||||||
| [V3-14](V3-14-gpx-interop.md) | GPX interoperability | S | V3-01 | Partially done (code only; needs real-device verification) |
|
| [V3-14](V3-14-gpx-interop.md) | GPX interoperability | S | V3-01 | Partially done (code only; needs real-device verification) |
|
||||||
| [V3-15](V3-15-auto-pause.md) | Auto-pause | M | V3-13 *(gated)* | Not started |
|
| [V3-15](V3-15-auto-pause.md) | Auto-pause | M | V3-13 *(gated)* | Not started |
|
||||||
| [V3-16](V3-16-visual-identity.md) | Visual identity | M | V3-04, V3-05 | Partially done (token-level identity shipped; needs outdoor device verification) |
|
| [V3-16](V3-16-visual-identity.md) | Visual identity | M | V3-04, V3-05 | Partially done (token-level identity shipped; needs outdoor device verification) |
|
||||||
|
| [V3-17](V3-17-osrm-hosting.md) | Self-hosted OSRM: investigate and stand one up | M | — *(needs a server — see the ticket's own note on the v3/v4 boundary)* | Not started |
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
@@ -40,15 +41,20 @@ backup are v4 — see [../BACKLOG.md](../BACKLOG.md).
|
|||||||
V3-01 ──┬────────────► V3-08 ──► V3-09
|
V3-01 ──┬────────────► V3-08 ──► V3-09
|
||||||
└──► V3-14 ▲
|
└──► V3-14 ▲
|
||||||
V3-07 ──────► V3-08 │
|
V3-07 ──────► V3-08 │
|
||||||
|
V3-17 ──────► V3-08 │
|
||||||
V3-02 ──► V3-03 │
|
V3-02 ──► V3-03 │
|
||||||
V3-04 ──┬──► V3-05 ──┬───────┘
|
V3-04 ──┬──► V3-05 ──┬───────┘
|
||||||
├──► V3-11 └──► V3-16
|
├──► V3-11 └──► V3-16
|
||||||
└──► V3-09
|
└──► V3-09
|
||||||
V3-13 ──► V3-15 (gate: may close unbuilt)
|
V3-13 ──► V3-15 (gate: may close unbuilt)
|
||||||
|
|
||||||
no dependencies: V3-01 · V3-02 · V3-04 · V3-06 · V3-07 · V3-10 · V3-12
|
no dependencies: V3-01 · V3-02 · V3-04 · V3-06 · V3-07 · V3-10 · V3-12 · V3-17
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**V3-08/V3-09 are deferred, on request**, pending V3-17 (self-hosted OSRM). See V3-17's
|
||||||
|
own note on why that also puts them in tension with this document's v3/v4 boundary —
|
||||||
|
unresolved by design, not an oversight.
|
||||||
|
|
||||||
## Three that carry more weight than their size suggests
|
## Three that carry more weight than their size suggests
|
||||||
|
|
||||||
**V3-01** ships the port's **first real migration**. The destructive fallback is gone, so
|
**V3-01** ships the port's **first real migration**. The destructive fallback is gone, so
|
||||||
@@ -56,7 +62,9 @@ getting `addColumn` plus a v1-database test right matters more than the feature
|
|||||||
V3-07 and V3-09 both add migrations behind it.
|
V3-07 and V3-09 both add migrations behind it.
|
||||||
|
|
||||||
**V3-08** forces a routing-engine decision with ongoing cost and vendor implications.
|
**V3-08** forces a routing-engine decision with ongoing cost and vendor implications.
|
||||||
Behind a `RoutingService` interface, mirroring what `LocationSource` did for GPS.
|
Behind a `RoutingService` interface, mirroring what `LocationSource` did for GPS. The
|
||||||
|
direction is decided (self-hosted OSRM); V3-17 does the actual standing-up, and V3-08 is
|
||||||
|
deferred until it exists.
|
||||||
|
|
||||||
**V3-13** is not code. It answers the three questions that have been open since v2, and
|
**V3-13** is not code. It answers the three questions that have been open since v2, and
|
||||||
**V3-15 may close unbuilt** as a result — a legitimate and probably likely outcome.
|
**V3-15 may close unbuilt** as a result — a legitimate and probably likely outcome.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# V3-08 — Road-snapped routing and ETA
|
# V3-08 — Road-snapped routing and ETA
|
||||||
|
|
||||||
**Phase** Route planning · **Depends on** V3-07, benefits from V3-01 · **Size** L · **Status** Not started
|
**Phase** Route planning · **Depends on** V3-07, benefits from V3-01, **blocked on V3-17**
|
||||||
|
· **Size** L · **Status** Deferred
|
||||||
|
|
||||||
## Goal
|
## Goal
|
||||||
Resolve the actual shortest path along roads between pins, and estimate how long the ride
|
Resolve the actual shortest path along roads between pins, and estimate how long the ride
|
||||||
@@ -11,6 +12,12 @@ This is what Dylan asked for. It is also the ticket with a **decision that canno
|
|||||||
deferred**: road-snapped routing needs a routing engine over OpenStreetMap data, and the
|
deferred**: road-snapped routing needs a routing engine over OpenStreetMap data, and the
|
||||||
choice has ongoing consequences.
|
choice has ongoing consequences.
|
||||||
|
|
||||||
|
**Decided, not deferred:** self-hosted OSRM (see the table below). What's actually
|
||||||
|
deferred is standing one up — that's [V3-17](V3-17-osrm-hosting.md), split out on
|
||||||
|
request because provisioning a server is a different kind of work from building the app
|
||||||
|
code that calls it, and this ticket cannot start until V3-17 has something to point
|
||||||
|
`RoutingService` at.
|
||||||
|
|
||||||
## Design
|
## Design
|
||||||
|
|
||||||
### Choosing an engine — decide before writing code
|
### Choosing an engine — decide before writing code
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# V3-09 — Follow a planned route while riding
|
# V3-09 — Follow a planned route while riding
|
||||||
|
|
||||||
**Phase** Route planning · **Depends on** V3-04, V3-08 · **Size** M · **Status** Not started
|
**Phase** Route planning · **Depends on** V3-04, V3-08 (itself blocked on V3-17) · **Size** M · **Status** Deferred
|
||||||
|
|
||||||
## Goal
|
## Goal
|
||||||
Pick a saved route before starting, see it on the live map underneath your actual track,
|
Pick a saved route before starting, see it on the live map underneath your actual track,
|
||||||
|
|||||||
88
docs/v3/V3-17-osrm-hosting.md
Normal file
88
docs/v3/V3-17-osrm-hosting.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# V3-17 — Self-hosted OSRM: investigate and stand one up
|
||||||
|
|
||||||
|
**Phase** Infrastructure · **Depends on** nothing · **Size** M · **Blocks** V3-08, V3-09 ·
|
||||||
|
**Status** Not started
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
Get a self-hosted OSRM instance running somewhere, so V3-08 (road-snapped routing and
|
||||||
|
ETA) has a real backend to build against instead of a deferred decision.
|
||||||
|
|
||||||
|
## Context
|
||||||
|
V3-08 named the choice of routing engine as "a decision that cannot be deferred," and
|
||||||
|
[the conversation that spawned this ticket](../v3/README.md) picked a direction without
|
||||||
|
picking a provider: **self-hosted OSRM**, over a hosted API (GraphHopper, Mapbox
|
||||||
|
Directions) or the public OSRM demo (explicitly not for production use).
|
||||||
|
|
||||||
|
**This ticket exists because that decision itself has a wrinkle worth naming up front:**
|
||||||
|
this whole v3 backlog's organizing principle, stated in `docs/BACKLOG.md`, is *"v3 is
|
||||||
|
everything that can be built with no server. v4 is everything that cannot."* A
|
||||||
|
self-hosted OSRM instance is a server. Strictly, that makes V3-08 and V3-09 — anything
|
||||||
|
that depends on this ticket — v4 work by the project's own definition, not v3, even
|
||||||
|
though they're filed under `docs/v3/` today and the routing itself has nothing to do
|
||||||
|
with the group-rides/accounts/backup programme that currently defines v4. Whether to
|
||||||
|
formally renumber them is a documentation decision for whoever picks this up next; this
|
||||||
|
ticket does not resolve it, only flags it so it isn't silently glossed over.
|
||||||
|
|
||||||
|
## Design
|
||||||
|
Two separable questions:
|
||||||
|
|
||||||
|
1. **Where does it run?** A small VPS (the same shape of box that would eventually host
|
||||||
|
the v4 group-ride server, so this could double as an early step toward that) versus
|
||||||
|
something serverless/managed. OSRM's own Docker image is the standard path either way.
|
||||||
|
2. **What data does it need?** A regional OSM extract, not the planet — start with
|
||||||
|
whatever region actually gets ridden (per `docs/LAUNCH.md`, this is presently a
|
||||||
|
friends-and-family app, so the region is small and known). [Geofabrik](https://download.geofabrik.de/)
|
||||||
|
publishes regional `.osm.pbf` extracts sized for exactly this.
|
||||||
|
|
||||||
|
Profiles matter for this app specifically (see V3-08's Design section): a motorcycle
|
||||||
|
route and a bicycle route between the same two pins should genuinely differ. OSRM ships
|
||||||
|
car/bike/foot profiles out of the box; a motorcycle profile is closer to car (mostly
|
||||||
|
avoids the walk-only restrictions bike profiles impose) but might want the twisty-road
|
||||||
|
preference a stock car profile doesn't have reason to express. Confirming that is part of
|
||||||
|
this ticket's investigation, not something to guess at now.
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
1. Pick and provision a host (see Design's first question)
|
||||||
|
2. Download and preprocess a regional extract with OSRM's own toolchain
|
||||||
|
(`osrm-extract` → `osrm-partition` → `osrm-customize`, or the older
|
||||||
|
`osrm-contract` pipeline depending on the OSRM version chosen)
|
||||||
|
3. Run `osrm-routed` behind whatever the host offers for TLS termination — the app will
|
||||||
|
be calling this over the public internet from riders' phones, so plain HTTP is not
|
||||||
|
an option
|
||||||
|
4. Confirm at least a car-equivalent and a bike profile both return sane routes for a
|
||||||
|
handful of real local pin pairs, by hand, before writing any app code against it
|
||||||
|
5. Write the resulting base URL and auth (if any) down for V3-08 to consume — as
|
||||||
|
configuration, never a hardcoded value, matching V3-08's own "no API key committed to
|
||||||
|
the repository" acceptance criterion, which applies here too even though there's no
|
||||||
|
third-party vendor to protect a key from — an open, unauthenticated routing endpoint
|
||||||
|
is still worth not publishing in a public repo
|
||||||
|
6. A basic uptime check of some kind — this becomes a real dependency the app relies on,
|
||||||
|
not a fire-and-forget script
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
- [ ] An OSRM instance is reachable over HTTPS from outside the host network
|
||||||
|
- [ ] Returns a road-following route for a real pin pair in the region actually ridden
|
||||||
|
- [ ] At least two distinct profiles (car-equivalent, bike) both work
|
||||||
|
- [ ] The endpoint and any credentials live in configuration, not source
|
||||||
|
- [ ] Documented: what's running, where, how to update the extract when it goes stale,
|
||||||
|
and what it costs (if anything) to keep running
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
Infrastructure, not app code — no `flutter test` coverage belongs to this ticket
|
||||||
|
directly. V3-08's own `FakeRoutingService`-driven tests are what verify the app's
|
||||||
|
behavior; this ticket's job is only to make the real thing exist for that fake to stand
|
||||||
|
in for.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
- **Ongoing hosting cost and maintenance**, however small — this is the first piece of
|
||||||
|
always-on infrastructure this project has taken on. Worth being honest that "no
|
||||||
|
server" stopped being true the moment this ticket is picked up, regardless of which
|
||||||
|
numbering bucket it ends up filed under.
|
||||||
|
- **OSM extracts go stale.** A road that didn't exist at extract time won't route.
|
||||||
|
Needs a refresh cadence, not a one-time setup.
|
||||||
|
- Regional extracts are cheap; do not reach for a planet-wide extract preemptively.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
Actually building V3-08/V3-09 against this once it exists — that's their ticket, not
|
||||||
|
this one. Turn-by-turn navigation, traffic-aware routing, anything beyond what stock OSRM
|
||||||
|
gives you.
|
||||||
Reference in New Issue
Block a user