One file per feature, in the v2 shape that worked: goal, context, design, implementation, acceptance criteria, tests, risks, out of scope -- written before implementing so the risks are on paper rather than walked into. Three carry more weight than their size suggests. V3-01 ships the port's first real migration, and since the destructive fallback is gone, getting addColumn and a v1-database test right matters more than the feature. V3-08 forces a routing-engine decision with ongoing cost, so it sits behind a RoutingService interface mirroring what LocationSource did for GPS. V3-13 is not code at all -- it answers the three questions open since v2, and V3-15 may close unbuilt as a result, which is a legitimate outcome. Several tickets record constraints that are easy to lose: no activity picker in front of Start, because the founding premise is press-and-go with gloves; the Route-to-Trip foreign key must not cascade, or deleting an old plan deletes the ride; V3-14 will deliberately break the parity harness by adding GPX <type>, and that expectation should be updated rather than the check dropped; and V3-16 must not regress the explicit text colours that exist because of the black-on-black bug. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
63 lines
2.7 KiB
Markdown
63 lines
2.7 KiB
Markdown
# V3-04 — Live map on the recording screen
|
|
|
|
**Phase** Live map · **Depends on** nothing · **Size** M · **Status** Not started
|
|
|
|
## Goal
|
|
While recording, show the path as it is drawn, on the recording screen.
|
|
|
|
## Context
|
|
v2 shipped without one deliberately: the phone rides in a pocket, so a live map would burn
|
|
battery for something nobody is looking at. **That decision is reversed** — Dylan wants it
|
|
for visual appeal, and because a mounted phone is now a real use case (V3-05).
|
|
|
|
The map component already exists (`RideMap`) and already handles per-segment polylines,
|
|
render-only decimation and the zoom clamp. This ticket is mostly about *lifecycle*, not
|
|
drawing.
|
|
|
|
## Design
|
|
Two constraints survive the reversal and are non-negotiable:
|
|
|
|
- **`RecordingEngine` must never reference a map.** Rendering belongs to a visible screen's
|
|
widget lifecycle. The engine already exposes everything needed.
|
|
- **No tile fetch or redraw while backgrounded.** A pocketed phone must cost exactly what
|
|
it costs today.
|
|
|
|
Feed the map from a stream of the current trip's points. `watchTripStats` exists but
|
|
returns aggregates; this needs the points themselves — add a `watchPointsForTrip` Drift
|
|
stream, which updates naturally on each writer flush (~2 s), not per fix.
|
|
|
|
Follow the rider: keep the latest point centred, with a manual-pan override that stops
|
|
auto-follow until re-enabled.
|
|
|
|
Behind the existing map toggle, off by default while it is unproven on battery.
|
|
|
|
## Implementation
|
|
1. `watchPointsForTrip(tripId)` in `AppDatabase`
|
|
2. Hoist the map above the stats card on the record screen, behind the toggle
|
|
3. `WidgetsBindingObserver` — on `AppLifecycleState.paused`, stop tile fetching; resume on
|
|
`resumed`. This is the load-bearing part.
|
|
4. Auto-follow with a pan override
|
|
5. Keep the numeric readout visible; the map must not push SPEED off screen (the record
|
|
screen already scrolls — see the overflow fix in `port/PROGRESS.md`)
|
|
|
|
## Acceptance criteria
|
|
- [ ] The path appears and extends while recording
|
|
- [ ] Backgrounding the app stops all tile activity, verified in a network log
|
|
- [ ] `RecordingEngine` still has no map import — grep it
|
|
- [ ] With the toggle off, no map widget is constructed at all
|
|
- [ ] Speed and elapsed remain visible without scrolling on a common phone size
|
|
|
|
## Tests
|
|
- Widget: map appears only when recording and the toggle is on
|
|
- Widget: lifecycle transition to paused stops the tile layer
|
|
- The existing map tests still pass
|
|
|
|
## Risks
|
|
- **Battery.** This is the whole reason v2 said no. Measure before defaulting it on
|
|
(V3-13).
|
|
- Redrawing per fix rather than per flush would be wasteful; drive from the database
|
|
stream, which is already batched.
|
|
|
|
## Out of scope
|
|
Mounted mode (V3-05). Other riders on the map (v4).
|