feat: portal-wide device selector — session-based, all pages now use selected device

- _portal_device_id() reads from session, falls back to DEVICE_NAME env var
- GET/POST /api/v1/portal/select-device for selector data + set
- Dropdown in server base.html topbar, JS populates from API, page reloads on change
- All portal pages (overview, trips, dashcam, DTC, device settings) now use selected device
This commit is contained in:
Mathieu Moran
2026-08-12 01:40:51 -04:00
parent 1556c65131
commit e30b85d218
6 changed files with 133 additions and 87 deletions
+12 -22
View File
@@ -1945,35 +1945,25 @@ agree on OBD and GPS state. BUGS.md Open section is empty. readme.md project sta
---
### Phase 27: Feature additions — ✅ DONE (3 shipped, 4 candidates remain)
**Completed 2026-08-12.** Three features shipped; remaining 4 are low-priority ideas
### Phase 27: Feature additions — ✅ DONE (4 shipped, 3 candidates remain)
**Completed 2026-08-12.** Four features shipped; remaining 3 are low-priority ideas
tracked in FEATURES.md.
**Shipped:**
- **FEAT-03 — Manual odometer baseline** (2026-08-11): Pi settings has "Odometer baseline
(km)". Dashboard shows `odometer_km = baseline + trip distance`. Pushes to server on save
via `POST /api/device-config/push`. Portal shows read-only synced value. Server overview
stat card. Four sync bugs fixed during implementation:
1. Sync overwrote Pi odometer with stale server value (`_store_synced_config` no longer touches it).
2. JS skipped `POST /api/device-config` when enabling sync (always-send fix).
3. Backend returned error when toggling sync with locked fields present (toggle-first fix).
4. `get_device_by_id()` missing `odometer_baseline` in SQL SELECT (added column, shifted indices).
Changed: `modules/app_settings.py`, `modules/app_sql.py`, `modules/app_device_sync.py`,
`modules/app_device_config.py`, `templates/settings.html`, `static/js/settings.js`,
`server/modules/db.py`, `server/modules/device_config.py`,
`server/templates/device_settings.html`, `static/js/portal-device-settings.js`,
`server/app.py`, `FEATURES.md`.
- **FEAT-06 — Trip ID column in history** (2026-08-11): Narrow `#ID` column on server
history (`data-show-id="1"`). Checkbox + batch-delete server-only (`data-batch-delete-url`).
Changed: `static/js/history.js`, `server/templates/history.html`.
- **FEAT-07 — Phone-hotspot auto-connect docs** (2026-08-11): Already implemented in
Phase 22; documented and verified with real Pixel hardware.
- **FEAT-03 — Manual odometer baseline** (2026-08-11)
- **FEAT-06 — Trip ID column in history** (2026-08-11)
- **FEAT-07 — Phone-hotspot auto-connect docs** (2026-08-11)
- **FEAT-05 — DTC history sync to server** (2026-08-12): Pi pushes DTC snapshots
via `POST /api/v1/dtc/batch`. Server diffs: insert/update/auto-clear. Portal
`/dtc` page with code, description, MIL, status, timestamps, delete. Skips
upload when OBD disconnected. Changed: `modules/app_upload.py`,
`server/sql/migrate_phase27_dtc.sql`, `server/modules/db.py`, `server/app.py`,
`server/templates/dtc.html`, `server/templates/base.html`.
**Remaining candidates (4):**
**Remaining candidates (3):**
1. **FEAT-01** — Parallel/concurrent chunked dashcam uploads (medium)
2. **FEAT-02** — QR / claim-code device pairing flow (medium)
3. **FEAT-04** — Replace SIM868 2G GSM with 4G LTE modem (large)
4. **FEAT-05** — DTC history synced to remote server (medium)
### Phase 28: Native Android companion app — 🚧 IN PROGRESS (low priority, always last)
**Renumbered from former Phase 26 on 2026-08-10 to make room for the road-test bug-fix phase.