# V3-09 — Follow a planned route while riding **Phase** Route planning · **Depends on** V3-04, V3-08 (itself blocked on V3-17) · **Size** M · **Status** Deferred ## Goal Pick a saved route before starting, see it on the live map underneath your actual track, and afterwards compare what you rode against what you planned. ## Context The payoff that makes V3-07 and V3-08 worth building, and the point where route planning meets the live map. Not navigation — no turn-by-turn, no voice. Just the line you meant to follow, drawn under the line you actually rode. ## Design Attach an optional `routeId` to `Trip`. That is enough for both the live overlay and the after-the-fact comparison. Live: the planned route in a muted colour, the recorded track drawn over it in the existing speed colours. Immediately obvious when you have left the plan. Afterwards, on trip detail: both lines, plus how far you deviated and how the real duration compared with the estimate — which also, over time, tells you how honest the ETA is. **Deliberately not:** rerouting, off-route alerts, or anything that demands attention while riding. A rider glancing at handlebars wants a picture, not an interruption. ## Implementation 1. `routeId` on `Trip` — **third migration** 2. Route picker on the record screen before Start, defaulting to none 3. Live map renders the planned polyline beneath the track 4. Trip detail renders both, with a comparison block 5. Deviation: max and mean distance from the recorded points to the planned polyline — `perpendicularDistanceMeters` already exists and is parity-proven ## Acceptance criteria - [ ] A route can be selected before starting, or not - [ ] Both lines render, visually distinguishable - [ ] Deviation and duration-vs-estimate appear on trip detail - [ ] A ride with no route behaves exactly as today - [ ] Deleting a route does not delete rides that referenced it ## Tests - Deviation maths against a known track and route - Repository: deleting a route nulls `routeId` rather than cascading to the trip — **the cascade direction here is the opposite of segments and is easy to get wrong** - Widget: both polylines present when a route is attached ## Risks The `Route` → `Trip` foreign key must **not** cascade. Deleting an old plan must never delete the ride you did. ## Out of scope Turn-by-turn, off-route alerts, rerouting.