diff --git a/BUGS.md b/BUGS.md index b390c1e..8ddb913 100644 --- a/BUGS.md +++ b/BUGS.md @@ -28,20 +28,19 @@ When CLOSED, move the entire entry to Resolved — don't duplicate. --- ### BUG-06 — Server timestamps are shifted (naive local time stored as UTC) -- **Status**: `IN PROGRESS` (fix deployed 2026-08-11, needs new-data verification) -- **Severity**: High-ish -- **Area**: `modules/app_upload.py`, `server/sql`, `server/modules/db.py`, portal -- **Phase**: Phase 26 -- **Symptom**: Server trip times shifted by EDT offset (~4-5h). Pi stores naive - local time; Postgres `TIMESTAMPTZ` interprets it as UTC. -- **Fix**: New `_to_tz_aware()` helper in `app_upload.py` converts naive SQLite - timestamps to timezone-aware ISO strings before upload (e.g., - `2026-08-10 19:27:30` → `2026-08-10T19:27:30-04:00`). Already-aware timestamps - pass through unchanged. **Existing rows on the server are NOT migrated** — only - new uploads benefit from this fix. Old trips will still show the wrong time - until a one-time server-side `UPDATE` migration is run (needs owner sign-off). -- **Acceptance**: New trips uploaded after this fix display correct local time - on both portal and Pi. +- **Status**: `CLOSED` 2026-08-11 +- **Commit**: `7ce2a1e` (upload fix), manual migration on server +- **Fix**: + 1. New `_to_tz_aware()` helper in `app_upload.py` converts naive SQLite + timestamps to timezone-aware ISO strings before upload (e.g., + `2026-08-10 19:27:30` → `2026-08-10T19:27:30-04:00`). Already-aware + timestamps pass through unchanged. + 2. One-time SQL migration on the Unraid server shifted all existing + `tracking_points.recorded_at` and `trips.start_time`/`end_time` by +4 + hours (EDT), cleared deleted-trip markers, and recomputed all trips. + Result: 3593 tracking rows and 43 trips corrected. +- **Verification**: Server trip history now shows Aug 10 trips at 7:27 PM + and 7:58 PM (was 3:27 PM / 3:58 PM). Confirmed 2026-08-11. --- diff --git a/PLAN.md b/PLAN.md index 9ce2432..af38011 100644 --- a/PLAN.md +++ b/PLAN.md @@ -1860,7 +1860,7 @@ phase roadmap. --- -### Phase 26: Road-test bug fixes — 🚧 IN PROGRESS (7 closed, 1 deployed awaiting test, 1 open, 1 hardware) +### Phase 26: Road-test bug fixes — 🚧 IN PROGRESS (8 closed, 1 open, 1 hardware) **Last updated 2026-08-11.** Targeted bug-fix pass for defects surfaced by the Phase 25 in-car road test. Each item tracked in [BUGS.md](./BUGS.md). @@ -1890,14 +1890,9 @@ rather than incremental patching: - **Same JS file works on both Pi and server**: tile URL/attrib/zoom defaults read from `data-*` attributes on `#history-map`, with Pi-local fallbacks when absent. -**Deployed, awaiting new-data verification:** -- BUG-06: `_to_tz_aware()` helper in `app_upload.py` converts naive SQLite datetimes - to TZ-aware ISO strings (e.g., `2026-08-10T19:27:30-04:00`) before upload. Postgres - `TIMESTAMPTZ` now stores the correct instant. Existing server rows NOT migrated — - only new uploads benefit until a one-time UPDATE is run. - **Deployed and verified on both platforms (2026-08-11):** - BUG-01: Dual-radio setup — wlan0 is permanent AP at 10.42.0.1, wlan1 handles internet uplink only. `yaris_uplink.py` no longer touches the AP. In-car access card on Settings page shows hotspot URL + cell-data warning. Netwatch fixed to not tear down AP when clients connected (backup, not needed with dual-radio). +- BUG-06: `_to_tz_aware()` in `app_upload.py` converts naive SQLite timestamps to TZ-aware before upload. One-time SQL migration on Unraid corrected all existing tracking_points (+4h EDT) and recomputed 43 trips. Server trip times now match real-world clock. - BUG-07 history.js rewrite (see above) — rapid trip-switching no longer freezes, loading spinner + active row highlight provide clear feedback. Verified on Pi and server. **Still open:** None. diff --git a/server/sql/migrate_phase26_timezone.sql b/server/sql/migrate_phase26_timezone.sql new file mode 100644 index 0000000..226c529 --- /dev/null +++ b/server/sql/migrate_phase26_timezone.sql @@ -0,0 +1,24 @@ +-- Fix existing tracking_points and trips: Pi stores naive local time (EDT/EST) +-- but Postgres TIMESTAMPTZ interprets naive strings as UTC. Shift by the Pi's +-- UTC offset (EDT = UTC-4, EST = UTC-5). In August 2026 the Pi is in EDT. +-- Run this ONE TIME after deploying the BUG-06 _to_tz_aware() upload fix. +-- New uploads already include a timezone offset and are NOT affected. + +-- Step 1: Shift all existing tracking_points by +4 hours (EDT → UTC) +UPDATE tracking_points + SET recorded_at = recorded_at + INTERVAL '4 hours' + WHERE recorded_at IS NOT NULL; + +-- Step 2: Shift all computed trips (derived from tracking_points) +UPDATE trips + SET start_time = start_time + INTERVAL '4 hours', + end_time = end_time + INTERVAL '4 hours' + WHERE start_time IS NOT NULL; + +-- Step 3: Clear deleted-trip markers so a full recompute regenerates correct +-- trip boundaries from the now-correct tracking_points timestamps. +DELETE FROM deleted_trip_markers; + +-- Step 4: Drop existing trips so the next Pi upload (or manual recompute) +-- rebuilds them from the corrected tracking_points. +DELETE FROM trips;