P1: Favourites Trends graph — FuelHistoryStore + TrendsView (Swift Charts)
- Shared/FuelHistory.swift: GitHub mirror read path (latest.json pointer + history/YYYY-MM-DD.json day files); day math (UTC noon keys), slim day decode with the shared price band, series + deltaSeries (vs-cheapest rebase), favourites-only app-group cache (90-day prune), parallel per-day fetches, 404/network = graph gap never error. - FuelPriceProvider: shared priceBand + mapGrades (single source for live + history decoding). - FuelBoard/TrendsView.swift: line chart in the Favourites tab via toolbar button + sheet; fuel capsule (fuels with favourites only), 7/30/90 range, Price/vs-cheapest toggle, per-station legend, price-display style on y-axis, empty/loading/retry states with honest copy; no widget in v1. - Localizable.strings: Trends keys. - 83 tests (13 history + URL regression): day math, band guard, series gaps, delta rebasing, prune, and the appendingPathComponent regression (relative URL resolution dropped /main — all fetches 404'd). - Sim-verified: favourites rows + TOP/deltas; sheet controls + building-up state with live first-snapshot date (archive has 1 day; lines render once >=2 snapshots). - Backlog: P1 Trends DONE (unmerged); P0 REMAINING = live provider chain + telemetry beacon.
This commit is contained in:
+15
-4
@@ -39,8 +39,10 @@ Status: TODO / IN PROGRESS / DONE / BLOCKED.
|
||||
(script ~/.hermes/scripts/mirror_push.py, log
|
||||
~/Library/Logs/fuelboard-mirror.log); manual trigger `launchctl start
|
||||
com.apt.fuelboard-mirror`; first snapshot 2026-08-15 landed + verified raw 200.
|
||||
REMAINING: app-side read (provider chain GitHub → relay → bundled dump) + the
|
||||
telemetry beacon.*
|
||||
REMAINING: live provider chain (GitHub → relay → bundled dump for CURRENT
|
||||
prices) + the telemetry beacon — NOTE: the HISTORY read path shipped with P1
|
||||
(FuelHistoryStore: latest.json + day files for starred stations, favourites-only
|
||||
app-group cache, 404 = gap never error, 90-day prune).*
|
||||
|
||||
## P1 — Soon
|
||||
|
||||
@@ -56,7 +58,7 @@ Status: TODO / IN PROGRESS / DONE / BLOCKED.
|
||||
Directions-to-cheapest `caadf18` + spoken hand-off `aed99e3`.*
|
||||
- [ ] **Siri: "Closest [fuel] station"** — same plumbing as cheapest, sort by
|
||||
distance instead of price. Free second phrase in the same `AppShortcutsProvider`.
|
||||
- [ ] **Favourites Trends graph** — price history chart for starred stations.
|
||||
- [x] **Favourites Trends graph** — price history chart for starred stations.
|
||||
Swift Charts (iOS 26 target) line chart in the Favourites tab; one series per
|
||||
favourite, fuel-scoped (station, fuel) pairs map 1:1 to the archive. Default =
|
||||
absolute price lines; toggle "vs cheapest favourite" re-baselines to 0 as signed
|
||||
@@ -64,7 +66,16 @@ Status: TODO / IN PROGRESS / DONE / BLOCKED.
|
||||
capsule fuel picker; range control 7/30/90 days; respects the price-display
|
||||
toggle; honest empty-state copy in Localizable.strings ("Prices are recorded from
|
||||
each refresh — check back in a few days"). No widget in v1 (one-kind rule).
|
||||
Depends on the P0 archive.
|
||||
Depends on the P0 archive. *DONE 2026-08-15 on feature/trends-history (unmerged):
|
||||
`Shared/FuelHistory.swift` (FuelHistoryStore: day math, slim day decode w/ shared
|
||||
band, series + deltaSeries, app-group favourites-only cache, parallel per-day
|
||||
fetches) + `FuelBoard/TrendsView.swift` (chart, fuel capsule, 7/30/90, Price/vs
|
||||
cheapest, per-station legend, empty/loading/retry states) + toolbar entry in
|
||||
FavouritesView + strings. 83 tests incl. URL regression (appendingPathComponent
|
||||
— URL(string:relativeTo:) dropped /main, all fetches 404'd). Sim-verified:
|
||||
favourites rows + TOP/deltas; sheet controls + honest empty state w/ live first-
|
||||
snapshot date. Pending: merge to main after device sideload test; lines render
|
||||
once ≥2 snapshots (archive warming daily).*
|
||||
|
||||
## P2 — Later
|
||||
|
||||
|
||||
Reference in New Issue
Block a user