Commit 4d9cd1b
Bugfixes 1 (#99)
* refactor(web): rewrite VehicleCommandCenter around shared range/command hooks
Redesigns the vehicle command center into modular components (hero, readiness strip, workspace, safety panel, activity feed) under features/system/components/command-center/, replacing the monolithic VehicleCommandCenter with domain-grouped command browsing and a dedicated /vehicles/{id}/command endpoint contract.
Introduces useRangeState with shared cross-page localStorage persistence (SHARED_RANGE_STORAGE_KEY) so date-range selections propagate between pages, and migrates all range-picker consumers (StatisticsPage, EnergyPage, ChargingListPage, CostAnalysisPage, DriveScorePage, DrivesListPage, DrivetrainHealthPage, EfficiencyPage, RouteEfficiencyPage, TripListPage, MyActivityPage) off ad-hoc useUrlString/useUrlBatch date defaults.
Adds a refetchInterval to useCommandLatest, normalizes command-query invalidation keys via a shared commandKeys helper, fixes MediaPlayerPage volume formatting to respect global precision, and removes an unstable Tesla charging-history sort parameter. Also relaxes several Go/TS command types to optional/nullable fields and adds CollapsibleCommandGroup vehicleKey prop rename.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: add Tesla vehicle management
Adds vehicle management APIs, partner-token support, cached metadata, enterprise operations, privacy-safe audit logging, and a React workspace with confirmation flows for paid and state-changing requests.
* fix: scope warranty data by vehicle
Move warranty API routes and Tesla requests to vehicle/VIN-scoped endpoints, update frontend hooks and widgets, and handle empty management responses with updated tests and SLO routes.
* refactor(web): use shared VehicleSelect in management page
Replace VehicleManagementPage's inline Select/Badge vehicle picker with the shared VehicleSelect component from @/components/forms, always showing the dropdown even for single-vehicle fleets. Removes now-unused useMemo-based option building and manual selected-name logic. Adds a test asserting the dropdown remains visible with one vehicle.
* feat(web): improve vehicle management views
Add structured views for options, specifications, warranties, subscriptions, and enterprise roles, with technical response details, improved endpoint cards, and expanded test coverage. Keep vehicle selection visible for single-vehicle fleets.
* refactor(web): SI-canonical fields in weekly digest
Converts the weekly-digest feature (types, useWeeklyDigest, and all section components) from mixed display-unit fields (km, kWh, min, Wh/km) to SI-canonical fields (m, Wh, s, Wh/m), converting only at the render boundary via useUnits(). Adds a shared formatEfficiencyFromSI helper and a useAlertHistory hook backed by a bounded /alerts?limit= query. Drive/charging fetches are now scoped to an explicit two-week analytical window instead of relying on default pagination, and alerts are filtered by vehicle_id. Updates all associated tests and i18n strings to match.
* feat(geofences): add charging place pricing
Add discovered charging places, effective-dated geofence rates, protected cost provenance, historical backfill, and drive/charge geofence attribution.
Expose pricing lifecycle, rate preview/apply, summaries, and activity APIs with a complete Charging Places workspace. Add migration, metrics, tracing, SLO dashboards, alerts, and coverage audit updates.
* fix(web): show breadcrumbs on all routes
Render Home and the current page for registered top-level routes, and move the quick-search hint into the global breadcrumb chrome. Update layout and breadcrumb tests accordingly.
* fix: repair charging SI values and geofences
Normalize Tesla charging energy and power to Wh/W, repair historical data, and preserve display-boundary conversions. Unify geofence and charging-place management with categories, alerts, bulk actions, search, and protected-session attribution.
* fix(web): refine range persistence and previews
Use rolling seven-day defaults with versioned shared date-range preferences, and improve charging-rate preview actions with clearer guidance, focus, and modal scrolling.
* feat(web): redesign digital twin with photo compositor overlay
Reworks VehicleTwin's SVG to trace real Model Y proportions (traced body/DLO paths, clipped shading, redesigned Gemini-style wheels/spokes, refined lights and glass gradients) and adds an optional photo mode: a new `teslaCompositor.ts` builds a Tesla configurator side-view render URL per paint/model, which VehicleTwin overlays live telemetry indicators on top of, aligning the SVG coordinate system to the photo's traced geometry. Falls back to the hand-drawn SVG if the photo fails to load. Passes `model` through from DigitalTwinWidget, DigitalTwinMiniWidget, and DigitalTwinPage. Also boosts paint palette opacity stops in vehicleColors.ts so the body reads as a solid painted surface rather than translucent.
* UPdated
* fix(web): animate vehicle twin wheel visibility
Keep vector wheels visible during drive-in and driving, then fade them out when the parked photo settles so the photo's wheels are revealed.
* Added Wheels
* fix(web): stop wheel spinner drift on slow photo load
Shrink the wheel crop radius (34→28) so the crop stays strictly on the rim face; larger radii dragged the tire's baked-in lighting/aero deflector around the hub, reading as a wobbling second wheel.
Also gate the entry spin animation on photo load timing: if the vehicle photo arrives more than 700ms after mount, the drive-in slide has already finished, so skip the spin instead of playing it against an already-parked car.
* fix(web): align VehicleTwin wheel spinners to hub centers
PhotoWheelSpinner previously derived crop position from viewBox-space wheel constants, causing the rotating crop to be visibly offset from the actual photo wheel. Now it reads hub centers and crop radius directly from COMPOSITOR_METRICS in image space, computed via imgScale/imgLeft/imgTop, so the crop and photo share one coordinate system. Also sets transformOrigin to 50% 50% for correct rotation pivot, tags spinners with data-wheel-spinner for testability, and adds a regression test asserting calibrated crop centers for both wheels.
* fix(web): feather wheel crop edge in VehicleTwin
Split the wheel spinner into a static masked container plus an inner rotating rotor, so the crop radius can extend to the rim/tire boundary while a radial-gradient mask feathers the outer 4px into transparency. This removes the hard-edged wobble previously caused by keeping the crop strictly inside the alloy face.
Updated COMPOSITOR_METRICS with wheelCropRadius=54 and new wheelCropFeather=4, and adjusted VehicleTwin tests to assert the new mask-image and rotor transform-origin.
* Add Tempo tracing backend and fix dashboard queries
Adds a Tempo container (compose + Helm) alongside the OTel collector for TraceQL, service-graph, and span-metrics dashboards, wiring the metrics generator to remote-write into Prometheus. Updates Grafana dashboard datasource UIDs, span-metric attribute names (OTel semconv 1.x: http.response.status_code, messaging.destination.name, etc.), and Prometheus scrape targets/ports for workers.
Rewrites many Grafana panel queries that were previously disabled or stubbed (ADR-002 placeholders) to pull from their now-available source tables (climate_snapshots, motor_snapshots, security_events, drive_telemetry, tesla_battery_passport_ledger, etc.) instead of signal_log placeholders. Adds vehicle/drive picker dropdowns backed by SQL variables in several dashboards, adds an automation-worker service to docker-compose.dev.yml, exposes /metrics on all workers via promhttp, and improves HTTP route attribution in the tracing middleware by tagging spans with chi's matched route after routing completes.
Also fixes the validate_grafana_signal_log.py script to use a relative dashboard path and substitute more template variables.
* fix(mqtt): ack poison payloads to unblock ingest
Fleet Telemetry ingestion stalled when malformed QoS 1 payloads accumulated in the broker's in-flight receive window. MQTT 3.1.1 has no NACK, so returning without acking never triggered a same-connection redelivery — it just consumed an in-flight slot permanently.
The PipelineSubscriber now gives every terminal failure (codec drop, VIN resolver infra error, unexpected pipeline error, non-shutdown deadline, recovered panic) one bounded DLQ publish attempt followed by an unconditional ACK. Only shutdown-driven cancellation leaves a message unacked so the broker preserves it for the next connection.
- Removed the process-local RedeliveryTracker, MaxRedeliveries/TrackerCapacity config, TESLA_MQTT_MAX_REDELIVERIES Helm setting, and mqtt.maxRedeliveries value.
- Ack is now idempotent via atomic CAS so a panicking DLQPublisher cannot double-ack.
- Observability: tesla_mqtt_dlq_writes_total{reason} label set changed to codec_drop, vin_resolver_error, other, dlq_publish_failure; dashboards filtering on dlq_max_redeliveries must update their selector.
- Updated tests, docs, and CHANGELOG accordingly, including a regression test that replays a 32-message poison burst matching the production EMQX inflight=32/32 signature.
* feat: durable onboarding state and component health alerts
Persist first-run setup completion so a Fleet Telemetry outage or an expired Tesla token no longer sends a configured installation back through onboarding.
Backend:
- Add migration 000230 creating the single-row `onboarding_state` table with a backfill for already-configured installs, plus `OnboardingStateRepo` (ratcheting `MarkComplete`).
- `GET /onboarding/status` now returns `setup_complete`/`setup_required` (with `is_complete` kept as a backward-compatible alias), `last_telemetry_at`, and an informational `telemetry_health`.
- Replace the watchdog's unconditional success recording with real probes for database, MQTT (including Fleet Telemetry subscriber health), Redis, Tesla auth, worker, and telemetry freshness.
- Add edge-triggered, cooldown-debounced outage/recovery notifications that respect per-channel preferences and fall back to direct dispatch when MQTT is down, with an in-memory channel/preference cache so database outages can still notify.
- Add a stable event-type catalog in `internal/notification` served at `GET /notifications/event-types`.
- Add `PipelineSubscriber.IsHealthy` and `Worker.HealthSnapshot`.
Frontend:
- Add `useRuntimeStatus`, notification event-type/preference hooks, a global `RuntimeHealthBanner`, and a per-channel `HealthAlertPreferencesPanel`.
- Route the onboarding gate off `setup_required`, add a runtime-health notice, extract the setup status band, and improve mobile layout/scrolling on the onboarding page.
Update OpenAPI docs and add unit/integration tests across all touched areas.
* Consolidate battery health analytics into one endpoint
Replace signal_log replay with bounded cagg_battery_daily aggregation for battery-health history, and merge the separate degradation/session queries into a single /analytics/battery-health response (parallel history/summary/charging-analysis loaders, in-memory cache with per-vehicle load coalescing, Server-Timing headers, and OTel tracing).
Frontend: drop useBatteryDegradation and useChargingSessionsPaginated in favor of the consolidated useBatteryHealthAnalytics hook (15-minute staleTime, no retry). Update BatteryHealthAnalytics/BatteryHealthSnapshot types to canonical SI field names (estimated_capacity_wh, range_m, odometer_m, etc.) and extract chart/insight logic from BatteryHealthPage into lazily-loaded, deferred (in-view) components: BatteryTrendCharts, BatteryChargingCharts, and shared helpers.
Add an SLO for battery-health request latency and update all affected tests/fixtures accordingly.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 2f6b98f commit 4d9cd1b
173 files changed
Lines changed: 8232 additions & 3021 deletions
File tree
- .github
- cmd
- automation-worker
- export-worker
- notification-worker
- slogen
- docs
- deployment
- observability
- public
- grafana
- dashboards
- infra
- system
- provisioning/datasources
- helm/teslasync
- files
- grafana/dashboards
- otel-collector
- templates
- internal
- api
- batterydegradation
- middleware
- notification
- onboarding
- status
- app
- database/user
- mqtt
- notification
- worker
- migrations
- observability
- otel-collector
- tempo
- prometheus
- scripts
- slo
- web/src
- api
- hooks
- __tests__
- components
- feedback
- layout
- vehicles
- __tests__
- features
- analytics/pages
- battery
- components/battery-health
- pages
- dashboard/widgets
- notifications
- components/channels
- pages
- onboarding
- components
- pages
- lib
- types
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
39 | 45 | | |
40 | 46 | | |
41 | 47 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
467 | 467 | | |
468 | 468 | | |
469 | 469 | | |
470 | | - | |
| 470 | + | |
471 | 471 | | |
472 | 472 | | |
473 | 473 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
5 | 18 | | |
6 | 19 | | |
7 | 20 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
295 | 296 | | |
296 | 297 | | |
297 | 298 | | |
| 299 | + | |
298 | 300 | | |
299 | 301 | | |
300 | 302 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
211 | 212 | | |
212 | 213 | | |
213 | 214 | | |
| 215 | + | |
214 | 216 | | |
215 | 217 | | |
216 | 218 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
| |||
384 | 385 | | |
385 | 386 | | |
386 | 387 | | |
| 388 | + | |
387 | 389 | | |
388 | 390 | | |
389 | 391 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
145 | 145 | | |
146 | 146 | | |
147 | 147 | | |
148 | | - | |
| 148 | + | |
149 | 149 | | |
150 | 150 | | |
151 | 151 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | | - | |
| 4 | + | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| |||
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
54 | | - | |
| 54 | + | |
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
66 | | - | |
| 66 | + | |
67 | 67 | | |
68 | 68 | | |
69 | 69 | | |
| |||
104 | 104 | | |
105 | 105 | | |
106 | 106 | | |
107 | | - | |
| 107 | + | |
108 | 108 | | |
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
112 | 112 | | |
113 | 113 | | |
114 | 114 | | |
| 115 | + | |
| 116 | + | |
115 | 117 | | |
116 | 118 | | |
117 | 119 | | |
| |||
139 | 141 | | |
140 | 142 | | |
141 | 143 | | |
142 | | - | |
| 144 | + | |
143 | 145 | | |
144 | 146 | | |
145 | 147 | | |
146 | 148 | | |
147 | 149 | | |
148 | 150 | | |
149 | 151 | | |
| 152 | + | |
| 153 | + | |
150 | 154 | | |
151 | 155 | | |
152 | 156 | | |
153 | 157 | | |
154 | 158 | | |
155 | 159 | | |
156 | 160 | | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
157 | 201 | | |
158 | 202 | | |
159 | 203 | | |
| |||
229 | 273 | | |
230 | 274 | | |
231 | 275 | | |
| 276 | + | |
232 | 277 | | |
233 | 278 | | |
234 | | - | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
235 | 282 | | |
236 | 283 | | |
237 | 284 | | |
238 | 285 | | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
239 | 305 | | |
240 | 306 | | |
241 | 307 | | |
| |||
245 | 311 | | |
246 | 312 | | |
247 | 313 | | |
248 | | - | |
249 | | - | |
250 | 314 | | |
251 | 315 | | |
252 | 316 | | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
253 | 350 | | |
254 | 351 | | |
255 | 352 | | |
256 | 353 | | |
257 | 354 | | |
| 355 | + | |
| 356 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
295 | 295 | | |
296 | 296 | | |
297 | 297 | | |
298 | | - | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
299 | 301 | | |
300 | 302 | | |
301 | 303 | | |
| |||
329 | 331 | | |
330 | 332 | | |
331 | 333 | | |
| 334 | + | |
332 | 335 | | |
333 | 336 | | |
334 | 337 | | |
| |||
503 | 506 | | |
504 | 507 | | |
505 | 508 | | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
506 | 536 | | |
507 | 537 | | |
508 | 538 | | |
| |||
532 | 562 | | |
533 | 563 | | |
534 | 564 | | |
| 565 | + | |
| 566 | + | |
535 | 567 | | |
536 | 568 | | |
537 | 569 | | |
| |||
697 | 729 | | |
698 | 730 | | |
699 | 731 | | |
| 732 | + | |
700 | 733 | | |
701 | | - | |
| 734 | + | |
0 commit comments