Muse spark - #106
Muse spark#106
Conversation
Two related charging-accuracy fixes: 1. Charge energy delta baselines now use State() strictly before StartedAt instead of at StartedAt, since Fleet Telemetry can emit the session-start batch after energy has already begun accumulating, causing undercounted energy in both the live handler and the completed-session tracker. 2. New Tesla Supercharger invoice overlay: ChargingHandler.Get resolves the vehicle's VIN and matches it against tesla_charging_history via a new FindBestMatch repo method (closest charge_start_datetime within a 2h window). When a match is found, billed energy/cost/currency/rate are added to the response and preferred for display on the frontend KPI tiles, with vehicle-measured energy shown as a secondary subtitle.
Treat spurious trip-meter resets and implausible counter jumps as discontinuities instead of driven distance. Adds reset/restore cursor logic and tests so include_fields zero snap-backs do not inflate FSD or driving aggregates.
Adds a live Grok powertrain read to Driving Dynamics using motor and chassis signals, with interpretation logic and tests. Also adds shared client-side pagination for FSD insight lists and DataTable-backed FSD tables.
Adds honesty-focused UI across the fleet dashboard, status bar, charging, battery, driving, and FSD views. Surfaces Supercharger bill site/fee metadata, preserves signal ingest timestamps for Tesla physics clocks, paginates physics evidence instead of truncating it, and fixes nav highlighting to prefer the most specific active route.
Add trip selection and date-scoped motor history, preserve active drives, and evenly sample backend history responses across the selected window.
Preserve and backfill charge coordinates without creating geofences from stale GPS, use Tesla billed energy for tariff pricing, and resolve date windows in the vehicle timezone.
Expand the drive detail FSD insights range to look around 24 hours so sparse counter bookends are included, preventing unknown/blank attribution for valid deltas. Adds backend and frontend regression coverage for the wider range behavior.
Adds drive_id support for FSD insights with a 7-day bookend lookup and focused attribution, while filtering negligible fidget drives so they do not steal sparse counter deltas. Updates drive detail and list UI to use the drive-scoped hook and omit unknown FSD badges.
Wire always-on charge autopilot, shared-charger queue planning, OCPP charge points, Tesla bill variance, session share reports, TCO fixed ledger, and related warranty, silence, and trip copilot surfaces. Register new i18n namespaces (autopilot, chargeQueue, ocpp) so the strict namespace audit and Docker web build pass. Fix TypeScript i18n count types, geofence hook typing, and AutomationFull.conflicts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep ChargingDetailPage share-session UI from muse-spark and billed-energy display from main (#104). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add per-vehicle autopilot profiles, TOU-based charge previews, health guardrails, and savings tracking. Integrate the configuration and preview panel into Smart Charge with API and UI tests.
Add next-charge recommendations comparing home TOU costs with Supercharger quotes, surfaced on dashboards and vehicle details. Expand automation, routine, and alert template catalogs with category filtering, localization, and tests.
Adds ecosystem automation presets and routine templates covering more Tesla commands, locations, charging, climate, media, and security scenarios. Updates catalogue tests and alert rule template coverage thresholds for the expanded preset set.
Watches Open-Meteo forecasts at each armed vehicle's home coords and pre-charges before storms: hourly evaluator raises the charge limit on fresh warnings when SOC is below target. Includes status/config/events API, StormGuardPanel on Emergency Resilience, and backend+UI tests.
Polls a per-vehicle ICS subscription, finds the next offsite event in the lead window, and preconditions once per event (5-minute evaluator). Includes next/config/now/runs API, ComfortPanel on Automations, offline refusal for the actuation endpoint, and backend+UI tests.
BuildClaimDraft assembles a ready-to-paste ticket from the owner issue, live warranty countdown, matched TSBs, ranked symptoms, and evidence. New claim-draft endpoint, ClaimDraftPanel on Service Intelligence, and backend+UI tests.
Flags recent drives that fit no named profile and sit far from their cluster centroid (median-adaptive score, deterministic pure function). New GET /driver-attribution/ghost-drives endpoint plus a GhostDrivesPanel on the Driver Attribution page with alert banner, score table, and one-click labelling that re-anchors the cluster.
Predicts queue waits per site and arrival time: hour-of-week demand from tesla_charging_sessions feeds Little's-law load plus an Erlang-C queue model (stalls estimated from peak overlap, documented lower bound). Read-only GET /waitoracle/sites + /forecast; WaitOraclePanel on the fleet sessions page with site/arrival pickers, verdict hero, best-hour suggestion, and the full-day wait curve.
Allow one Tesla 1-mile wire quantum above the physical travel threshold so valid 10-second counter samples are retained, while still rejecting implausible jumps. Add unit and drive analytics regression coverage.
Route new panels through Icons, SI seconds for wait forecasts, queryPolicy/scopedPath on hooks, ICS host allowlist, catalog i18n keys, and useDataState fatalError surfaces. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Slice 1 of Journey Autopilot: persistent journey_sessions (planned/active/paused/completed/aborted, one active per vehicle, race-safe conditional transitions) plus append-only versioned plans for future replan diffs. New /journeys page with session manager: plan form, status filter, lifecycle actions driven by server next_statuses, plan history. Also regenerates routetemplates_gen.go, absorbing 19 previously unregenerated routes so the freshness gate passes.
Refresh the VitePress theme, navigation, landing pages, and onboarding. Add generated screen catalogues, Markdown page tools, and new homepage visuals.
Cap journey list limits at 100 with safe defaults and tests. Localize status labels and inherit theme-aware icon colors.
Add English translations for planned, active, paused, completed, and aborted journey statuses.
Update localized JourneyPanel assertions and align journey namespace ordering in English manifests.
Keep localized journey status tests; take main's trips/journey i18n manifest order. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The duplicate journey key can cause translations to be ignored or rejected by strict JSON tooling.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Updates Journey localization strings and adjusts JourneyPanel tests for translated labels.
Changes:
- Adds English Journey translations.
- Updates status and accessible-label test expectations.
File summaries
| File | Summary |
|---|---|
web/src/i18n/en/locale-trips.json |
Critical: duplicate top-level journey key; merge additions into the existing object. |
web/src/features/trips/components/JourneyPanel.test.tsx |
Updates assertions for localized UI text. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Drop the push trigger (matches main) and only read runner input on workflow_dispatch so GitHub does not reject the workflow file. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the push trigger so required checks fire, but never read inputs.runner except on workflow_dispatch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Required checks plus path filters produced 0-job workflow-file failures. Run on every push/PR with ubuntu-latest so the job starts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Unindented heredocs made GitHub treat the workflow as a file issue (0 jobs). Run the checks from .github/scripts/si_canonical_gate.py. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Enable CGO for -race on ubuntu-latest, drop make from proto-gen-check, and capture teslasync-api logs in the nightly k6 job. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
One or more custom setup steps configured for this repository failed during this Copilot code review run: Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review. Note You can configure setup steps for Copilot code review separately from Copilot cloud agent with a |
There was a problem hiding this comment.
Note
Copilot was unable to run its full agentic suite in this review.
Pull request overview
Copilot reviewed 96 out of 134 changed files in this pull request and generated 5 comments.
Suppressed comments (2)
web/src/components/feedback/Toast.test.tsx:1
- Because
useToastis now globally wrapped intest-setup.tsto swallow the missing-provider error, this test no longer exercises the real production contract (thatuseToastthrows outsideToastProvider). Considervi.unmock('@/components/feedback/Toast')(or an explicit local mock) in this test file so it validates the actual module behavior, while keeping the global fallback for unrelated component tests.
web/src/api/hooks/useAnnotations.test.tsx:1 - In ESM test files, static
importstatements are evaluated before module body code runs. If the module under test (or its dependents) is imported in this file, a plainvi.unmock(...)at top-level may not consistently take effect before the import is resolved. To make the intent robust, use Vitest’s hoisted APIs (for example a hoisted unmock) and ensure the unmock happens before importing the module that should be real.
| handlermw "github.com/ev-dev-labs/teslasync/internal/handler/middleware" | ||
| v1handlers "github.com/ev-dev-labs/teslasync/internal/handler/v1" | ||
| actioncenterhandler "github.com/ev-dev-labs/teslasync/internal/handler/v1/actioncenter" | ||
| fleetstatehandler "github.com/ev-dev-labs/teslasync/internal/handler/v1/fleetstate" |
| fleetStateHandler := fleetstatehandler.NewFleetStateHandler(fleetstatesvc.New(fleetstatesvc.Options{ | ||
| Vehicles: vehicledb.NewVehicleRepo(db), | ||
| Resolver: vehicleSvc, | ||
| Live: liveSignalStore, |
| - '.github/workflows/si-canonical-gate.yml' | ||
| workflow_dispatch: | ||
| inputs: | ||
| runner: |
| group: si-canonical-gate-${{ github.ref }} | ||
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | ||
|
|
||
| permissions: |
grafana/k6-action isolated localhost from compose-published :8080. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Unauthenticated CI hits ForwardAuth 401/403; only 5xx should fail api_errors. Write summary.json next to the script so the k6 container can persist it.
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Copilot reviewed 97 out of 135 changed files in this pull request and generated 1 comment.
Suppressed comments (4)
web/src/features/resale-vault/components/BatteryCertificatePanel.tsx:1
- Adding the entire
verifyMutationobject to the dependency array can cause the effect to re-run on renders where React Query returns a new mutation-result object identity, potentially re-triggeringmutate()multiple times whiledatais stillundefined. Prefer depending on stable members (e.g.,verifyMutation.mutate) and the specific flags you read in the effect, or keep the original narrowed dependency with an explicit justification if the mutation object is guaranteed stable in this codebase.
tests/k6/api_smoke.js:1 - This check now treats essentially all 3xx/4xx responses as acceptable (including 404/403/429), which makes the smoke test far less useful and can hide real regressions behind a 'passing' run. Consider keeping the original intent (e.g.,
200success, plus explicitly allowed unauthenticated statuses like401) and failing on unexpected 4xx to preserve signal; if you need to tolerate specific additional statuses, list them explicitly.
web/src/features/charging/pages/SmartChargePage.test.tsx:1 - Using
document.getElementById(...)bypasses Testing Library queries and can make tests less aligned with user interactions/accessibility. Since the components have labels, preferscreen.getByLabelText(...)/getByRole(...)(optionally with a selector) so the test fails if the control becomes inaccessible or the form semantics change.
web/src/test-setup.ts:1 - Catching all errors here can unintentionally mask real issues thrown by
actual.useToast()(e.g., unrelated runtime bugs), making failures harder to diagnose. If the goal is only to handle the 'used outside provider' invariant, consider checking the thrown error (message/type) and rethrowing unknown errors so genuine defects still surface in tests.
The grafana/k6 image is non-root, so handleSummary could not write tests/k6/summary.json and the artifact upload warned with no files.
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Copilot reviewed 97 out of 135 changed files in this pull request and generated 3 comments.
Suppressed comments (8)
tests/k6/api_smoke.js:1
- These checks now treat any 4xx (including 404/403) as acceptable, which can mask broken routes, missing auth configuration, or API contract regressions in the smoke test. Consider keeping the earlier explicit allowlist (e.g., 200 and 401 for no-auth runs), or broaden narrowly (e.g., allow 200/401/403) rather than accepting all <500.
tests/k6/api_smoke.js:1 - These checks now treat any 4xx (including 404/403) as acceptable, which can mask broken routes, missing auth configuration, or API contract regressions in the smoke test. Consider keeping the earlier explicit allowlist (e.g., 200 and 401 for no-auth runs), or broaden narrowly (e.g., allow 200/401/403) rather than accepting all <500.
tests/k6/api_smoke.js:1 - These checks now treat any 4xx (including 404/403) as acceptable, which can mask broken routes, missing auth configuration, or API contract regressions in the smoke test. Consider keeping the earlier explicit allowlist (e.g., 200 and 401 for no-auth runs), or broaden narrowly (e.g., allow 200/401/403) rather than accepting all <500.
tests/k6/api_smoke.js:1 - These checks now treat any 4xx (including 404/403) as acceptable, which can mask broken routes, missing auth configuration, or API contract regressions in the smoke test. Consider keeping the earlier explicit allowlist (e.g., 200 and 401 for no-auth runs), or broaden narrowly (e.g., allow 200/401/403) rather than accepting all <500.
web/src/test-setup.ts:1 - Catching all errors here can hide genuine bugs inside
actual.useToast()(not just the 'missing provider' case), causing tests to silently pass while production would fail. Prefer only falling back for the specific expected error (e.g., checkerr instanceof Errorand match the known message), and rethrow otherwise.
web/src/features/notifications/components/QuietHoursGuide.test.tsx:1 - In ESM, static
importstatements are evaluated before module body code, so thisvi.unmock('react-i18next')may not reliably take effect before../../../i18n(or other imports) pull inreact-i18next. To make the unmock deterministic, use module isolation + dynamic import (e.g.,vi.resetModules()andawait import(...)aftervi.unmock(...)), or move the global mock out of shared setup and mock per-test where needed.
web/src/features/charging/pages/SmartChargePage.test.tsx:1 - Using
document.getElementByIdbypasses Testing Library’s user-centric queries and can make tests more coupled to implementation details. Now that IDs are present, prefer accessible queries likescreen.getByRole('combobox', { name: /Rate Plan/i })/screen.getByLabelText(...), orscreen.getByTestIdif there’s a deliberate testing hook.
web/src/test-setup.ts:1 - The PR description is still a template (
Closes #empty, no change type selected, checklist unchecked), but the diff includes broad test-harness changes, backend refactors, dependency bumps, and CI workflow updates. Please update the PR description to clearly state intent/scope and link the relevant issue(s) so reviewers know what behavior is expected to change.
| handlermw "github.com/ev-dev-labs/teslasync/internal/handler/middleware" | ||
| v1handlers "github.com/ev-dev-labs/teslasync/internal/handler/v1" | ||
| actioncenterhandler "github.com/ev-dev-labs/teslasync/internal/handler/v1/actioncenter" | ||
| fleetstatehandler "github.com/ev-dev-labs/teslasync/internal/handler/v1/fleetstate" |
| // SPA's multi-tab / SSE-burst thundering herd collapses into ONE storage | ||
| // read. Failures are never cached and every caller gets its own copy. | ||
| fleetStateHandler := v1handlers.NewFleetStateHandler(fleetstatesvc.New(fleetstatesvc.Options{ | ||
| fleetStateHandler := fleetstatehandler.NewFleetStateHandler(fleetstatesvc.New(fleetstatesvc.Options{ |
| path = line[6:].strip() | ||
| current_file = None if path == "dev/null" else path |
|
One or more custom setup steps configured for this repository failed during this Copilot code review run: Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review. Note You can configure setup steps for Copilot code review separately from Copilot cloud agent with a |
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Copilot reviewed 97 out of 135 changed files in this pull request and generated 4 comments.
Suppressed comments (6)
tests/k6/api_smoke.js:1
- These checks now treat any 4xx (including 404/403/429) as acceptable, which significantly weakens the smoke test’s ability to catch broken routing, missing endpoints, or auth regressions. If the intent is 'allow unauthenticated runs', consider restricting 'acceptable' to known outcomes (e.g., 200 and 401/403) and failing on unexpected 4xx like 404.
tests/k6/api_smoke.js:1 - These checks now treat any 4xx (including 404/403/429) as acceptable, which significantly weakens the smoke test’s ability to catch broken routing, missing endpoints, or auth regressions. If the intent is 'allow unauthenticated runs', consider restricting 'acceptable' to known outcomes (e.g., 200 and 401/403) and failing on unexpected 4xx like 404.
tests/k6/api_smoke.js:1 - These checks now treat any 4xx (including 404/403/429) as acceptable, which significantly weakens the smoke test’s ability to catch broken routing, missing endpoints, or auth regressions. If the intent is 'allow unauthenticated runs', consider restricting 'acceptable' to known outcomes (e.g., 200 and 401/403) and failing on unexpected 4xx like 404.
tests/k6/api_smoke.js:1 - These checks now treat any 4xx (including 404/403/429) as acceptable, which significantly weakens the smoke test’s ability to catch broken routing, missing endpoints, or auth regressions. If the intent is 'allow unauthenticated runs', consider restricting 'acceptable' to known outcomes (e.g., 200 and 401/403) and failing on unexpected 4xx like 404.
web/src/test-setup.ts:1 - Catching errors thrown by a hook (
actual.useToast()) inside another hook-like function can mask real provider/React-context issues and makes failures harder to diagnose (tests may pass even when components accidentally use Toast outside a provider). A more test-friendly approach is to fully stubuseToastto a no-op API by default in test setup, and explicitly opt into the real implementation only in tests that need provider behavior (viavi.unmock+ rendering insideToastProvider).
web/src/features/charging/pages/SmartChargePage.test.tsx:1 - Using
document.getElementByIdin RTL tests couples the test to implementation details and bypasses accessibility-focused queries. Since the PR adds stableids, it’s likely the inputs are properly labeled—preferscreen.getByRole('combobox', { name: /rate plan/i })/screen.getByRole('spinbutton', { name: /max amps/i })(orgetByLabelText) so the test asserts user-visible semantics and fails when labeling/accessibility regresses.
| handlermw "github.com/ev-dev-labs/teslasync/internal/handler/middleware" | ||
| v1handlers "github.com/ev-dev-labs/teslasync/internal/handler/v1" | ||
| actioncenterhandler "github.com/ev-dev-labs/teslasync/internal/handler/v1/actioncenter" | ||
| fleetstatehandler "github.com/ev-dev-labs/teslasync/internal/handler/v1/fleetstate" |
| // SPA's multi-tab / SSE-burst thundering herd collapses into ONE storage | ||
| // read. Failures are never cached and every caller gets its own copy. | ||
| fleetStateHandler := v1handlers.NewFleetStateHandler(fleetstatesvc.New(fleetstatesvc.Options{ | ||
| fleetStateHandler := fleetstatehandler.NewFleetStateHandler(fleetstatesvc.New(fleetstatesvc.Options{ |
| def iter_added_lines(diff_text: str): | ||
| current_file = None | ||
| for line in diff_text.splitlines(): | ||
| if line.startswith("+++ "): | ||
| path = line[6:].strip() | ||
| current_file = None if path == "dev/null" else path |
| push: | ||
| pull_request: |
|
One or more custom setup steps configured for this repository failed during this Copilot code review run: Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review. Note You can configure setup steps for Copilot code review separately from Copilot cloud agent with a |
|
One or more custom setup steps configured for this repository failed during this Copilot code review run: Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review. Note You can configure setup steps for Copilot code review separately from Copilot cloud agent with a |
Description
Closes #
Type of Change
Checklist
Screenshots (if applicable)