# TransitPin — CHANGELOG ## 2026-08-09 — Initial: migrate to Git - Migrated project to Git with ITPP standards (.gitignore, README template, docs-check CI). ## 2026-07-29 ### Added - **Follow Driver** — each driver card in Dispatch tab has a 📍 button. Clicking centers the map on that driver and pans to follow their position updates every 3s. Dragging the map or clicking again unfollows. Blue glow on active follow. (JS: `window.followedDriverId`, `dispatchMap.panTo` in position handler) - **Wake Lock API** — driver page requests `navigator.wakeLock.request('screen')` when GPS tracking starts, preventing screen dim/lock. Released on stop. Re-acquired automatically on visibility change. "🔒 Screen awake" / "⚠️ Screen may dim" indicator below GPS grid. - **TomTom traffic overlay** — 🚦 toggle button on Dispatch tab. Toggles real-time traffic flow tiles (green/yellow/red overlay) on the Leaflet map. ### Fixed - **Permission 600→644** — driver.html and manifest were root-only, blocked Caddy from serving them. - **Caddy WebSocket route** — changed from `handle_path /ws/driver/*` to `handle_path /ws/driver*` to match bare `/ws/driver` path. - **Position ID field mismatch** — server broadcasts `position` with `driverId` field, but admin JS was looking for `d.id`. Fixed `updateDriverPosition`, `updateDriverCard`, `updateDriverStatus`, and `driver-offline` handler to accept both `id` and `driverId`. - **TomTom tile URL** — was missing `/absolute/` in the path, causing 400 errors on all traffic tiles. Fixed from `/tile/flow/{z}/{x}/{y}.png` to `/tile/flow/absolute/{z}/{x}/{y}.png`. - **JS scope on toggleTraffic** — function was local inside `initDispatch()`, invisible to onclick. Changed to `window.toggleTraffic`. - **Parent portal dashboard crash after login** — `escapeHtml()` was called in 10 places throughout `renderDashboard()` and `renderEmergencyContacts()`, but the function was defined as `escHTML()` (abbreviated). This threw `ReferenceError` immediately after login, leaving a blank dashboard. Fix: added `const escapeHtml = escHTML;` alias at line 1121. Root cause: function was named one way during message rendering code (`escHTML`) and inconsistently named in dashboard/emergency contacts code (`escapeHtml`). ### Architecture - WebSocket relay running as `village-express.service` (systemd, port 8210) - Caddy reverse-proxies `/ws/driver*` → `127.0.0.1:8210` for TLS - Driver PWA streams GPS every 3s via `watchPosition` - Dispatchers receive real-time position broadcasts --- ## Future Projects ### Native Background Tracking (Capacitor Wrapper) The PWA approach cannot keep GPS running when the phone screen locks. No browser-based solution supports this. **Next step:** Wrap the driver PWA with Capacitor to produce real iOS/Android apps with native background geolocation permissions (`CLLocationManager` on iOS, `FusedLocationProviderClient` on Android). The existing HTML/JS frontend stays — Capacitor wraps it with native APIs. **Requirements:** - Capacitor CLI + native iOS/Android project scaffolding - `cordova-plugin-background-geolocation` or Capacitor's built-in geolocation plugin with background mode - App store deployment for iOS (Apple Developer account needed) - Play Store or direct APK for Android **Estimated effort:** 1-2 days for Capacitor setup + background plugin integration. App store submission adds 1-2 weeks for review. **No rewrite needed** — the web code stays; Capacitor adds the native shell.