Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
5065dfc
feat(web): add RangePicker, Popover primitive, and useRangeState hook
atulmgupta May 11, 2026
5e8f00c
feat(web): migrate 15 pages to <RangePicker> + add presetsOnly mode
atulmgupta May 11, 2026
e1d1d41
feat(web): right-align RangePicker into PageContainer actions slot on…
atulmgupta May 11, 2026
4af12f8
feat(web/timeline): add RangePicker to /timeline (presetsOnly, header…
atulmgupta May 11, 2026
63e55cf
feat(web/locations): add RangePicker to /locations (header right)
atulmgupta May 11, 2026
21d503b
feat(speed-profile): add RangePicker with start/end bounds (no hardco…
atulmgupta May 11, 2026
8062696
feat(regen-efficiency): add RangePicker with start/end bounds (no har…
atulmgupta May 11, 2026
9b3f250
feat(web/charging-curve): add RangePicker to /charging-curve (header …
atulmgupta May 11, 2026
f8a19b2
feat(web/charging-heatmap): add RangePicker to /charging-heatmap (hea…
atulmgupta May 11, 2026
a7724dd
feat(web): add RangePicker to CommandHistory + AlertsPage
atulmgupta May 11, 2026
6ed3d28
feat(software-updates): add RangePicker with start/end bounds
atulmgupta May 11, 2026
75c2c35
feat(web/tesla-charging): add RangePicker to history + sessions pages
atulmgupta May 11, 2026
b977488
feat(web): single-line RangePicker trigger + SecurityAccess range filter
atulmgupta May 11, 2026
3a8473a
feat(web/api-logs): unify date filter to RangePicker; drop hardcoded …
atulmgupta May 11, 2026
6454308
refactor(web): vehicle-first ordering on PageContainer.actions across…
atulmgupta May 11, 2026
3dd78aa
refactor(web): unify vehicle selector via useSelectedVehicle store
atulmgupta May 11, 2026
9598788
feat(analytics): migrate Fleet Analytics to RangePicker; drop hardcod…
atulmgupta May 11, 2026
f0a28d2
refactor(command-history): vehicle-first actions + useSelectedVehicle…
atulmgupta May 11, 2026
b6bcc73
feat(telemetry): unify Signal Log/Explorer range filter to canonical …
atulmgupta May 11, 2026
26cab7d
refactor(signal-explorer): unify control row layout with Signal Log V…
atulmgupta May 11, 2026
f3c97d0
refactor(tesla-charging-history): unify filter row into PageContainer…
atulmgupta May 11, 2026
4e73afd
fix(ui): make Slider track visible everywhere; align with Input/Selec…
atulmgupta May 11, 2026
7814a5e
refactor(sleep-efficiency): canonical [Vehicle][RangePicker] actions
atulmgupta May 11, 2026
1baf914
refactor(tire-pressure): lift filters to PageContainer.actions
atulmgupta May 11, 2026
262930c
fix(layout): wrap PageHeader actions on narrow viewports
atulmgupta May 11, 2026
931a8f6
refactor(fsm-debugger): use global Vehicle + RangePicker filters
atulmgupta May 11, 2026
09a388b
fix(filters): honor exact RangePicker windows in FSM Debugger + Sleep…
atulmgupta May 11, 2026
7b3f481
refactor(notifications): consolidate /alerts and /notifications into …
atulmgupta May 11, 2026
c9da1f9
refactor(filters): roll out global VehicleSelect across all vehicle-s…
atulmgupta May 11, 2026
1bd18f3
refactor(filters): wire 8 more pages to global Vehicle store
atulmgupta May 11, 2026
4c02ca8
feat(filters): add global RangePicker to /route-efficiency and /drive…
atulmgupta May 11, 2026
43659b7
ui(drives): lift RangePicker into actions row alongside VehicleSelect
atulmgupta May 11, 2026
4d7c484
feat(filters): wave 4 -- VehicleSelect global rollout to 10 more pages
atulmgupta May 11, 2026
65ac40f
fix(chatbot): make /chatbot mobile-friendly
atulmgupta May 11, 2026
4660557
feat(filters): add VehicleSelect to /live-monitor with SSE filter
atulmgupta May 11, 2026
c6232c0
feat(nav): consolidate location pages under Maps section + move API L…
atulmgupta May 11, 2026
d79c573
feat(integrations): promote Tesla account sub-sections from /settings…
atulmgupta May 12, 2026
8a61985
feat(integrations): promote Gas Price Auto-Poll to its own page
atulmgupta May 12, 2026
ab5f205
Move sidebar help row to footer StatusBar (HelpSegment)
atulmgupta May 12, 2026
ac2eabd
Remove "Notifications moved" advisory panel from /settings
atulmgupta May 12, 2026
ecc4aaa
Split 2FA + Active Sessions into /account pages under new Account sid…
atulmgupta May 12, 2026
75d6186
Split Privacy into /account/privacy under Account sidebar category
atulmgupta May 12, 2026
5b6fb71
Move settings JSON export/import into /backup, drop duplicate from Se…
atulmgupta May 12, 2026
f56e2a8
Rename 'Controls' sidebar group to 'Vehicle Commands'
atulmgupta May 12, 2026
f8f7cff
Add 'Smart Actions' sidebar group; move Studio + Automations under it
atulmgupta May 12, 2026
457e8b8
Move Anomaly Detection from Infrastructure to Analytics sidebar group
atulmgupta May 12, 2026
9171a75
Split 'Assistant' sidebar group into 'AI' (Chatbot) and 'Media' (Medi…
atulmgupta May 12, 2026
07b6b4d
Rename 'Media' sidebar group to 'Entertainment'
atulmgupta May 12, 2026
4832013
refactor(settings): drop redundant Tesla integration and Fleet API pl…
atulmgupta May 12, 2026
819a3af
refactor(layout): split Integrations into Tesla Account / Tesla API /…
atulmgupta May 12, 2026
50d1f26
Phase 1: System Status redesign — operator-grade self-hosted dashboard
atulmgupta May 12, 2026
ffe13d4
refactor(signals): consolidate 5 telemetry pages onto shared componen…
atulmgupta May 12, 2026
8796672
refactor(system-status): wire every accordion to live backend data
atulmgupta May 12, 2026
75c1f4b
fix(system-status): chip nav + density — open accordions, scroll past…
atulmgupta May 12, 2026
68957df
fix(system-status): dedupe components list — drop camelCase aliases
atulmgupta May 12, 2026
65c193e
fix(StickyChipBar): scroll the actual scroll container, not window
atulmgupta May 12, 2026
94f7d34
fix(system-status): Health rows scroll to in-page accordion, not stal…
atulmgupta May 12, 2026
99624e7
feat(system-status): Phase 2 operator-grade enhancements
atulmgupta May 12, 2026
cb5d5a9
feat(system-status): enrich Tesla API usage card with burn rate, fore…
atulmgupta May 12, 2026
e34df9c
feat(system-status): per-vehicle telemetry liveness in pipeline card
atulmgupta May 12, 2026
62074ab
feat(system-status): per-instance worker visibility for horizontally-…
atulmgupta May 12, 2026
3ff3261
refactor(system-status): remove duplicate Diagnostics section
atulmgupta May 12, 2026
324fbbf
feat(system-status): Phase 2 follow-up — Status API v1, SSE, incident…
atulmgupta May 12, 2026
ecc403e
fix(HealthRow): left-align label inside button-rendered rows
atulmgupta May 12, 2026
007fc3f
ui(system-status): align title with body, widen to max-w-5xl, tighten…
atulmgupta May 12, 2026
f07c829
refactor(admin): remove /admin page; relocate audit log + frontend er…
atulmgupta May 12, 2026
43d83c8
ui(charging-session-card): show end SOC % inside the progress ring
atulmgupta May 12, 2026
0b27e23
fix(digital-twin): badge no longer shows Offline when vehicle is driv…
atulmgupta May 12, 2026
51358ad
Remove Changelog page; revamp sidebar & nav
atulmgupta May 12, 2026
de24648
fix(api): migrate signal_log queries to canonical SI schema
atulmgupta May 12, 2026
c355384
feat(drives,charging,alerts): Drive History redesign + reusable list …
atulmgupta May 12, 2026
7734034
feat(dashboard): mobile-friendly dashboard widgets pass
atulmgupta May 12, 2026
c50919e
feat(command-palette): prefix filters for scoped command-palette sear…
atulmgupta May 12, 2026
cc4a9c4
fix(grafana): thread prev/next nav links across all 16 infra dashboards
atulmgupta May 12, 2026
36e9e7f
feat(db): add SI-aware convert_pressure_pa / distance_m / speed_mps
atulmgupta May 13, 2026
bb7973c
feat(scripts): add Grafana dashboard sync script for production
atulmgupta May 13, 2026
c2ed7d1
fix(grafana): SI canonicalisation, ADR-002 revivals, unit-of-measure …
atulmgupta May 13, 2026
e3ceb72
fix(web): tolerate empty/whitespace locale across Intl call sites
atulmgupta May 13, 2026
5666118
fix(docs): quote OpenAPI description containing colon-space
atulmgupta May 13, 2026
3af2bcb
fix(api,web): interpret date-range filters in user's local tz
atulmgupta May 13, 2026
580e3bf
fix(web): adapt /signals history response to typed BE shape
atulmgupta May 13, 2026
0cd19bb
fix(dashboard): render mobile breakpoint as flex stack
atulmgupta May 13, 2026
0e121a6
feat(alerts): per-rule notification message templates (Phase-50, ADR-…
atulmgupta May 13, 2026
940bf9b
feat(signals): Grafana-style workspace redesign (Phase-51)
atulmgupta May 13, 2026
9479ae4
chore(settings): remove unused Google Maps API Key field
atulmgupta May 13, 2026
8e92862
feat!: honor user display preferences across all UI surfaces
atulmgupta May 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,6 @@ ENGINEERING_GUIDELINES.md
scripts/check-loc.js
/.github/prompts
/.github/prompts/db-refactor/logs

# Redesign working notes (Phase 50+ /charging redesign)
REDESIGN-NOTES.md
1,007 changes: 542 additions & 465 deletions CHANGELOG.md

Large diffs are not rendered by default.

50 changes: 43 additions & 7 deletions cmd/notification-worker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"

"github.com/ev-dev-labs/teslasync/internal/alertmsg"
"github.com/ev-dev-labs/teslasync/internal/apilog"
"github.com/ev-dev-labs/teslasync/internal/config"
"github.com/ev-dev-labs/teslasync/internal/database"
Expand Down Expand Up @@ -345,7 +346,21 @@ continue
if !result.Triggered {
continue
}
dispatchComputedMetricNotification(rule, vid, result, channels, mqttClient)
// Resolve a friendly vehicle name for the message template,
// falling back silently when the vehicle is missing — the
// renderer is tolerant of an empty VehicleName.
vehicleName := ""
for _, v := range allVehicles {
if v != nil && v.ID == vid {
if v.DisplayName != "" {
vehicleName = v.DisplayName
} else {
vehicleName = v.VIN
}
break
}
}
dispatchComputedMetricNotification(rule, vid, vehicleName, result, channels, mqttClient)
}
}
}
Expand Down Expand Up @@ -376,22 +391,43 @@ func vehiclesForRule(rule *models.AlertRule, all []*models.Vehicle) []int64 {
func dispatchComputedMetricNotification(
rule *models.AlertRule,
vehicleID int64,
vehicleName string,
result computed.Result,
channels []*models.NotificationChannel,
mqttClient pahomqtt.Client,
) {
// Phase-50 / ADR-005: route computed-metric dispatch through the
// shared alertmsg package so the message is rendered identically to
// the telemetry path. Without this, a custom msg_template on a
// computed-metric rule would be ignored and the IncludeTitle toggle
// would never reach the transports.
msgCtx := alertmsg.BuildContext(rule, vehicleName, nil, map[string]any{
"Severity": rule.Severity,
"MetricValue": result.Value,
"MetricPrevValue": result.PreviousValue,
"MetricChangePct": result.PercentChange,
})
title := alertmsg.RenderTitle(rule, msgCtx)
body := alertmsg.RenderBody(rule, msgCtx)
if !rule.IncludeTitle && body == "" {
body = rule.Name
}
suppressTransportTitle := !rule.IncludeTitle

dispatched := 0
for _, ch := range channels {
if ch == nil || !ch.Enabled {
continue
}
req := &notification.Request{
ChannelType: ch.Type,
Config: ch.Config,
Title: rule.Name,
Message: result.Message,
ChannelID: ch.ID,
AlertID: rule.ID,
ChannelType: ch.Type,
Config: ch.Config,
Title: title,
Message: body,
ChannelID: ch.ID,
AlertID: rule.ID,
Severity: rule.Severity,
SuppressTransportTitle: suppressTransportTitle,
}
if pubErr := notification.Publish(mqttClient, req); pubErr != nil {
log.Error().
Expand Down
2 changes: 1 addition & 1 deletion docs/public/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4260,7 +4260,7 @@ paths:
post:
operationId: submitExportJob
summary: Submit async export job
description: Submits an asynchronous export job for large datasets. CSV exports are v2-only and use SI canonical filenames and columns: teslasync-drives-v2.csv, teslasync-charging-v2.csv, teslasync-trips-v2.csv. Drive headers include distance_m, duration_s, max_speed_mps; trip headers include total_distance_m, total_energy_wh, total_duration_s.
description: "Submits an asynchronous export job for large datasets. CSV exports are v2-only and use SI canonical filenames and columns: teslasync-drives-v2.csv, teslasync-charging-v2.csv, teslasync-trips-v2.csv. Drive headers include distance_m, duration_s, max_speed_mps; trip headers include total_distance_m, total_energy_wh, total_duration_s."
tags: [Export]
requestBody:
required: true
Expand Down
8 changes: 4 additions & 4 deletions grafana/dashboards/infra/api-performance.json
Original file line number Diff line number Diff line change
Expand Up @@ -835,9 +835,9 @@
"tags": [],
"targetBlank": false,
"title": "◀ Prev",
"tooltip": "TeslaSync - Telemetry Pipeline",
"tooltip": "TeslaSync - Trace Explorer (Tempo TraceQL)",
"type": "link",
"url": "/d/teslasync-infra-telemetry"
"url": "/d/teslasync-infra-trace-explorer"
},
{
"asDropdown": true,
Expand All @@ -859,9 +859,9 @@
"tags": [],
"targetBlank": false,
"title": "Next ▶",
"tooltip": "TeslaSync - Rules Engine",
"tooltip": "TeslaSync - Auth Login Deep-Dive (always-sampled)",
"type": "link",
"url": "/d/teslasync-infra-cep"
"url": "/d/teslasync-infra-auth-deep-dive"
}
]
}
38 changes: 38 additions & 0 deletions grafana/dashboards/infra/auth-deep-dive.json
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,43 @@
"targets": [{ "datasource": { "type": "tempo", "uid": "DS_TESLASYNC_TEMPO" }, "queryType": "traceql", "query": "{ span.http.route = \"/api/v1/auth/login\" && duration > 1s }", "limit": 30, "refId": "A" }],
"datasource": { "type": "tempo", "uid": "DS_TESLASYNC_TEMPO" }
}
],
"links": [
{
"asDropdown": false,
"icon": "bolt",
"includeVars": true,
"keepTime": true,
"tags": [],
"targetBlank": false,
"title": "◀ Prev",
"tooltip": "TeslaSync - API Performance",
"type": "link",
"url": "/d/teslasync-infra-api-perf"
},
{
"asDropdown": true,
"icon": "external link",
"includeVars": true,
"keepTime": true,
"tags": [
"teslasync"
],
"targetBlank": false,
"title": "⚡ TeslaSync",
"type": "dashboards"
},
{
"asDropdown": false,
"icon": "bolt",
"includeVars": true,
"keepTime": true,
"tags": [],
"targetBlank": false,
"title": "Next ▶",
"tooltip": "TeslaSync - Rules Engine",
"type": "link",
"url": "/d/teslasync-infra-cep"
}
]
}
8 changes: 4 additions & 4 deletions grafana/dashboards/infra/cep-rule-engine.json
Original file line number Diff line number Diff line change
Expand Up @@ -464,9 +464,9 @@
"tags": [],
"targetBlank": false,
"title": "◀ Prev",
"tooltip": "TeslaSync - API Performance",
"tooltip": "TeslaSync - Auth Login Deep-Dive (always-sampled)",
"type": "link",
"url": "/d/teslasync-infra-api-perf"
"url": "/d/teslasync-infra-auth-deep-dive"
},
{
"asDropdown": true,
Expand All @@ -488,9 +488,9 @@
"tags": [],
"targetBlank": false,
"title": "Next ▶",
"tooltip": "TeslaSync - Infrastructure Health",
"tooltip": "TeslaSync - Critical Flow Latency (Phase-44 instrumented)",
"type": "link",
"url": "/d/teslasync-infra-health"
"url": "/d/teslasync-infra-critical-flows"
}
]
}
38 changes: 38 additions & 0 deletions grafana/dashboards/infra/critical-flows.json
Original file line number Diff line number Diff line change
Expand Up @@ -184,5 +184,43 @@
"targets": [{ "datasource": { "type": "tempo", "uid": "DS_TESLASYNC_TEMPO" }, "queryType": "traceql", "query": "{ name =~ \"mqtt.*|normalize.*\" && duration > 500ms }", "limit": 30, "refId": "A" }],
"datasource": { "type": "tempo", "uid": "DS_TESLASYNC_TEMPO" }
}
],
"links": [
{
"asDropdown": false,
"icon": "bolt",
"includeVars": true,
"keepTime": true,
"tags": [],
"targetBlank": false,
"title": "◀ Prev",
"tooltip": "TeslaSync - Rules Engine",
"type": "link",
"url": "/d/teslasync-infra-cep"
},
{
"asDropdown": true,
"icon": "external link",
"includeVars": true,
"keepTime": true,
"tags": [
"teslasync"
],
"targetBlank": false,
"title": "⚡ TeslaSync",
"type": "dashboards"
},
{
"asDropdown": false,
"icon": "bolt",
"includeVars": true,
"keepTime": true,
"tags": [],
"targetBlank": false,
"title": "Next ▶",
"tooltip": "TeslaSync - DB & Tesla API Span Breakdown (Tempo)",
"type": "link",
"url": "/d/teslasync-infra-db-tesla-breakdown"
}
]
}
38 changes: 38 additions & 0 deletions grafana/dashboards/infra/db-tesla-breakdown.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,5 +182,43 @@
"targets": [{ "datasource": { "type": "tempo", "uid": "DS_TESLASYNC_TEMPO" }, "queryType": "traceql", "query": "{ span.kind = \"client\" && span.http.url =~ \".*tesla.*\" && span.duration > 2s }", "limit": 30, "refId": "A" }],
"datasource": { "type": "tempo", "uid": "DS_TESLASYNC_TEMPO" }
}
],
"links": [
{
"asDropdown": false,
"icon": "bolt",
"includeVars": true,
"keepTime": true,
"tags": [],
"targetBlank": false,
"title": "◀ Prev",
"tooltip": "TeslaSync - Critical Flow Latency (Phase-44 instrumented)",
"type": "link",
"url": "/d/teslasync-infra-critical-flows"
},
{
"asDropdown": true,
"icon": "external link",
"includeVars": true,
"keepTime": true,
"tags": [
"teslasync"
],
"targetBlank": false,
"title": "⚡ TeslaSync",
"type": "dashboards"
},
{
"asDropdown": false,
"icon": "bolt",
"includeVars": true,
"keepTime": true,
"tags": [],
"targetBlank": false,
"title": "Next ▶",
"tooltip": "TeslaSync - Fleet Telemetry Server",
"type": "link",
"url": "/d/teslasync-infra-fleet-telemetry"
}
]
}
40 changes: 39 additions & 1 deletion grafana/dashboards/infra/fleet-telemetry.json
Original file line number Diff line number Diff line change
Expand Up @@ -572,5 +572,43 @@
"current": { "text": "Prometheus", "value": "prometheus" }
}
]
}
},
"links": [
{
"asDropdown": false,
"icon": "bolt",
"includeVars": true,
"keepTime": true,
"tags": [],
"targetBlank": false,
"title": "◀ Prev",
"tooltip": "TeslaSync - DB & Tesla API Span Breakdown (Tempo)",
"type": "link",
"url": "/d/teslasync-infra-db-tesla-breakdown"
},
{
"asDropdown": true,
"icon": "external link",
"includeVars": true,
"keepTime": true,
"tags": [
"teslasync"
],
"targetBlank": false,
"title": "⚡ TeslaSync",
"type": "dashboards"
},
{
"asDropdown": false,
"icon": "bolt",
"includeVars": true,
"keepTime": true,
"tags": [],
"targetBlank": false,
"title": "Next ▶",
"tooltip": "TeslaSync - Infrastructure Health",
"type": "link",
"url": "/d/teslasync-infra-health"
}
]
}
8 changes: 4 additions & 4 deletions grafana/dashboards/infra/infrastructure.json
Original file line number Diff line number Diff line change
Expand Up @@ -1461,9 +1461,9 @@
"tags": [],
"targetBlank": false,
"title": "◀ Prev",
"tooltip": "TeslaSync - Rules Engine",
"tooltip": "TeslaSync - Fleet Telemetry Server",
"type": "link",
"url": "/d/teslasync-infra-cep"
"url": "/d/teslasync-infra-fleet-telemetry"
},
{
"asDropdown": true,
Expand All @@ -1485,9 +1485,9 @@
"tags": [],
"targetBlank": false,
"title": "Next ▶",
"tooltip": "TeslaSync - Sessions & Business Metrics",
"tooltip": "TeslaSync - MQTT Pipeline Trace View (Tempo)",
"type": "link",
"url": "/d/teslasync-infra-sessions"
"url": "/d/teslasync-infra-mqtt-pipeline-traces"
}
]
}
38 changes: 38 additions & 0 deletions grafana/dashboards/infra/mqtt-pipeline-traces.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,43 @@
"targets": [{ "datasource": { "type": "tempo", "uid": "DS_TESLASYNC_TEMPO" }, "queryType": "traceql", "query": "{ span.messaging.system = \"mqtt\" && status = error }", "limit": 30, "refId": "A" }],
"datasource": { "type": "tempo", "uid": "DS_TESLASYNC_TEMPO" }
}
],
"links": [
{
"asDropdown": false,
"icon": "bolt",
"includeVars": true,
"keepTime": true,
"tags": [],
"targetBlank": false,
"title": "◀ Prev",
"tooltip": "TeslaSync - Infrastructure Health",
"type": "link",
"url": "/d/teslasync-infra-health"
},
{
"asDropdown": true,
"icon": "external link",
"includeVars": true,
"keepTime": true,
"tags": [
"teslasync"
],
"targetBlank": false,
"title": "⚡ TeslaSync",
"type": "dashboards"
},
{
"asDropdown": false,
"icon": "bolt",
"includeVars": true,
"keepTime": true,
"tags": [],
"targetBlank": false,
"title": "Next ▶",
"tooltip": "TeslaSync - Observability Self-Health (OTel Collector + Tempo)",
"type": "link",
"url": "/d/teslasync-infra-otel-self-health"
}
]
}
Loading
Loading