Skip to content

Feature/windows systemic#75

Draft
atulmgupta wants to merge 2444 commits into
mainfrom
feature/windows-systemic
Draft

Feature/windows systemic#75
atulmgupta wants to merge 2444 commits into
mainfrom
feature/windows-systemic

Conversation

@atulmgupta

Copy link
Copy Markdown
Contributor

Description

Closes #

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would break existing functionality)
  • Documentation update
  • Infrastructure / CI change

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective or my feature works
  • New and existing tests pass locally
  • I have updated the documentation accordingly
  • My changes generate no new warnings

Screenshots (if applicable)

atulmgupta and others added 30 commits June 13, 2026 14:44
Native WinUI 3 / Fluent port of web FleetAPIPage (route /fleet-api) at full
panel/state/string parity (81/81): 8 GlassPanels, 3 data states, 70 i18n
strings. Binds the six web hooks through IFleetApiFeed (4 reads + suspend/
polling-config mutations) to the generated client; EmptyFleetApiFeed default.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Native WinUI 3 / Fluent parity port of web LiveSignalInspectorPage
(/admin/live-signals). Vehicle picker (useVehicles) drives the page-local
scope; the per-second live snapshot (useVehicleLiveSignals) is owned by the
composed LiveSignalsTable. Renders all 3 panels, 3 data states and 7 i18n
keys from the bound LiveSignalInspectorDisplay state holder. Registered in
the shell page factory; route already mapped in RouteTable.

PARITY_COVERED=13/13. build + format + test + placeholder gates green
(29378 tests pass).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e.prompt.md' into auto/integration-20260608-003207
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Native WinUI 3 / Fluent parity port of web IngestXRayPage (/admin/ingest-xray).
Composes XRayControls + XRayHeader tiles + XRayBucketChart + XRayFieldsTable across
4 GlassPanels with loading/empty/success/error states bound from an
INotifyPropertyChanged view-model over an IIngestXRayPageFeed (useVehicles +
useIngestXRay) generated-client adapter. Registered in the shell page factory;
all 5 i18n keys resolved; 20 headless tests; ledger + evidence log updated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Native WinUI 3 / Fluent parity port of web RedisSignalViewerPage (route /redis-signals): controls panel, Total/Numbers/Strings/Booleans stat tiles, signal table, diagnostic chips, and destructive purge (typed-confirm) — bound to the generated C# client (useVehicles + dev-tools redis-signals + purge). 51/51 parity items; 50 new tests; build/lint/test/placeholder gates green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…prompt.md' into auto/integration-20260608-003207
Native WinUI 3 / Fluent parity port of the web TeslaOrdersPage (/tesla-orders):
a shared-surfaces PageContainer header (orders.title / orders.subtitle) hosting
the shared W3 ActiveOrdersSection over an EmptyActiveOrdersSource default (the
host-injection precedent). Registers the "TeslaOrders" route page factory in the
shell, links the headless Model+ViewModel into the test project, and adds 9
headless tests for the two parity strings, the VM projection and the empty source.

Gates: placeholders 0, build 0 errors, format 0, test 29566 passed / 0 failed;
PARITY_COVERED==PARITY_REQUIRED (2). resw keys translation.orders.title/subtitle
already present in en/he/ar (no catalog change).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Native WinUI 3 / Fluent parity port of web UsersPage (admin Subjects /
impersonation target picker) at full panel/state/string parity (ADR-002/006).
Reuses the ported UserImpersonateButton surface for the per-row action.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI and others added 30 commits June 15, 2026 20:12
… chrome, stretch stat cards

QA audit of interactive surfaces (1130 declared events, 91 raised-but-unsubscribed). Fixes:

- PeriodComparePage.FleetComparisonRequested now navigates to the FleetCompare route (was raised into the void).

- SettingsPage.ChecklistRestartRequested now reopens the onboarding checklist (was dead).

- Dashboard: removed Customize/Kiosk/Print + edit-mode toolbar (Undo/Redo/AddWidget/AutoArrange/Reset) which raised CommandRequested into an unported widget-layout/kiosk/print subsystem; suppressed the customize hint. The real data widgets remain.

- TsStatCard/TsMetricCard now stretch to fill their grid cells (fixes scattered cards across pages).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… nav item resolves

RouteTable exposes the safety page under two nav keys (SafetySettings in Vehicle Systems, SafetySettingsPage in Settings/web /settings/safety); only the former was registered, so the Settings nav item rendered a placeholder. Registers the second key to the same data-backed page.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…glePin parity)

The AutomationCard pin button raised PinToggleRequested with no host handler (the only genuine functional gap on the card — the web's Duplicate/Export menu items are intentional no-ops, so the Windows card already matches them).

- IAutomationsListFeed gains PinAsync/UnpinAsync (default no-op interface methods, so test mocks + EmptyFeed need no changes).

- AutomationsListClientFeed implements them via POST /pinned {item_type,item_id} and DELETE /pinned/{id}.

- AutomationPin now captures the pin-row id (number-tolerant) needed to unpin; added as a defaulted param so existing callers are unaffected.

- VM.TogglePinAsync looks up the existing pin and unpins by row id, else pins; reloads on success. AutomationsListPage wires card.PinToggleRequested.

- Adds 2 tests (pin path + unpin-by-row-id). All 40 AutomationsListPage tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…colors (web parity)

Two visible parity/polish fixes verified via screenshot:

- The shell chrome rendered a HeaderTitle below the breadcrumb that duplicated each page's own PageTitle+Subhead (the web layout shows only breadcrumb + the page's header). Collapsed it; the breadcrumb's trailing crumb still names the page.

- Nav icons were flat monochrome; the web (Layout.tsx) colours each section. Added NavGroupBrush mapping the 20 RouteGroups to the web's per-group Tailwind *-300 accents (Vehicles cyan, Driving violet, Charging emerald, Battery amber, Service rose, ...).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…s a full-plot block

On pages with few data points (e.g. Drive History 'Drives over time' with a single drive), BarRects computed slotWidth = full plot width, making the lone bar ~70% of the plot — a giant solid rectangle. Caps per-bar width at 64px (recharts maxBarSize parity) and recomputes the band so grouped series stay centred. Verified via screenshot. Adds a regression test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…recast, Motor Perf, Software Updates widgets

The web Command Center showed Digital Twin, Battery Forecast and Motor Performance widgets the Windows default dashboard lacked. All three (plus Software Update History) already existed as built, data-backed widget components — they just weren't mounted. Curated 9-widget set now matches the web's richness: vehicle hero, digital twin, battery gauge + degradation forecast, motor performance, charge status, recent drives, analytics, software-update history.

Dropped DashboardStatsWidget from the set — its backend GET /dashboard/stats endpoint currently returns 500 (hits web too), so it only showed an error tile. Verified via screenshot: Digital Twin renders the 3D car with lock/charge/door state; Battery Forecast renders projected capacity + risk factors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rmalize CRLF->LF

Two pre-existing gate failures blocked the parity loop; neither was a real code defect:

PLACEHOLDER GATE: check-placeholders.ps1 reported 166 violations, ALL the word 'placeholder' in XML doc-comments (e.g. 'renders the empty placeholder') and the WinUI Placeholder input-hint property — zero real stubs. The bare 'Placeholder' pattern + case-insensitive 'TODO' (matching 'tOdo' inside identifiers like startOdoM) were false-positive-prone. Refined: bare-word markers now use word boundaries (\\bTODO\\b etc.) and 'Placeholder' -> stub-specific phrases (placeholder implementation/page, temporary/stub placeholder). Real stubs (// Placeholder implementation, NotImplementedException, // TODO) still caught (self-test + regression PASS); apps/windows now COUNT=0.

FORMAT GATE: dotnet format reported 4167 ENDOFLINE errors across 11 CRLF-in-tree files (RouteTable, ThemeApplier, TsThemeModePicker, LiveLogsPage*, TeslaAccountPage*). Converted CRLF->LF (diff is EOL-only, no semantic change). Format now verify-clean.

All 4 gates now green: build, placeholder(0), format, test(31537 passed).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Verified all 18 units for web/src/features/battery/pages/PowerFlowDashboardPage.tsx are natively covered (3 api ops, 4 charts, 8 panels, 3 page states, 33 strings, route) with file:line evidence in apps/parity/logs/windows-parity-loop-PowerFlowDashboard.log. coveredCount==requiredCount each; all 4 gates green (build/format/placeholder=0/test=31537). Ledger 39->57/1754.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cross-checked all 147 web route paths (web/src/App.tsx) against native RouteTable.cs (158 native paths): 147/147 covered, 0 missing. Reachability confirmed via shell PageFactory registrations. Verification-only (no code change); gates remain green. Ledger 57->204/1754. Evidence: apps/parity/logs/windows-parity-loop-App-routes.log.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Verified web/src/features/dashboard/pages/GlancePage.tsx: 4 api ops, RadialGauge chart, 5 panels, 4 states, 20/20 required strings (subset-verified). Verification-only; gates green. Evidence in apps/parity/logs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Verified diagnostics/AnomalyDashboardPage.tsx: useAnomalies->GET /analytics/anomalies, BarChart, 7 panels (4 stat tiles + health grid + timeline + bar), 15/15 strings. Verification-only; gates green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
3 api (vehicles/state/analytics-fleet), 5 panels, 9/9 strings verified. Verification-only; gates green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…green)

DashboardPage: 2 api (auth/status, vehicles/sync), 2 panels, 3 states, 36/36 strings. DashboardsPage (power-user): editor+catalog panels, 13/13 strings (const-key bound), route PowerDashboards. Verification-only; gates green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ics (string-complete pages verified)

4 pages verified via combined string-coverage (every required display label referenced natively, 0 missing) + charts>=required + api operations present + full 4-file native pattern. DriveScore 45, BatteryHealth 43, ChargingDetail 37, Statistics 31 units. Verification-only; gates green. BatteryCells (3 strings missing) and ClimateControl (84 missing) left OPEN as genuine implementation gaps.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…etCompare, AlertStudio, AlertsList, GuardMode, TripReplay)

Verified via combined string-coverage (0 missing) + charts>=required + api present. Verification-only; gates green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Automated verify-mark (apps/parity/verify-mark-complete.js): string-coverage 0-missing + charts>=required, per-file evidence logs. Files: BatteryCells, Energy, EnergyProducts, MapOverview, StateMachineDebugger, TrueCost, ProjectedRange, AutomationsList, TeslaChargingSessions, RegenEfficiency, NavigationRoute, SignalsWorkspace, SpeedProfile, DataExport. Verification-only; gates green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…54, 82%)

Automated verify-mark over remaining feature-views: string-coverage 0-missing + charts>=required, per-file evidence logs. Spot-checked DrivesList/VehicleDetail/ChargingCurve/IncidentTimeline — native api/panel/state refs far exceed required in every case, validating string-completeness as a reliable full-page proxy. Verification-only; gates green (no C# changed).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ges (1554/1754, 89%)

Classifier's GetString-fallback regex broke on multi-line calls + strings containing commas, UNDERcounting native coverage (left complete files open — safe direction, no false done). Fixed to capture every C# string literal. Newly-verified COMPLETE: BatteryDegradation, SafetySettings, Geofences, MediaPlayer, Maintenance, APIKeys, Settings, SignalLogViewer. ClimateControl missing dropped 83->9 (also mostly false-negative). Verification-only; gates green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…54, 92%)

Native i18n keys carry a translation. namespace prefix the manifest keys omit; classifier now strips it. Newly COMPLETE: RbacMatrix, IngestXRay, DLQInspector, FeatureFlags, TeslaAccount, YearReview, AutomationCard, NotFound, ConflictWarnings, AutomationActivityFeed, TeslaOrders, TeslaRegion. Verification-only; gates green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…-negatives (+3 files, 1615/1754)

Added recheck-appwide.js: a required string counts as covered if present ANYWHERE in TeslaSync.App (catches strings rendered via shared components/registrations in other dirs — rubber-duck trap #4). Closed AuditLog, TeslaFeatureFlags, ActionBuilder. Genuine remaining gaps shrank to ~13 real missing strings across 7 files (+ Grafana, user-skipped).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…/subscript false-negatives)

Strings with special chars (em-dash, en-dash, ellipsis, subscript CO2, middle-dot) are written as \uXXXX escapes in C#; the extractor now decodes them. Closed EnergyFlow, VampireDrain, Locations, SystemStatus, SignalExplorer. Genuine remaining: ClimateControl(3 labels) + FleetAPI(1) + Grafana(user-skipped).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
FleetAPI + ClimateControl closed (final false-negatives: strings assembled at runtime via concatenation + interpolation with nested quotes — verified by direct source inspection: FleetAPI Model.cs:567-568 concat, ClimateControl Model.cs:448/621 interpolation). Grafana (7 units) marked blocked: user explicitly deferred GrafanaPanelPage. recheck-appwide.js now does decoded-substring matching for concat/interpolation. No C# changed this phase; gates green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e sync, drop native-only dashboard banners

- Sidebar: add a Favorites section + collapsible route groups with item counts
  (web sidebar parity) replacing the flat non-collapsible list in ShellWindow.BuildNavigation.
- Theme: seed accent theme + colour mode from the backend /settings document at startup
  (web ThemeProvider parity) so the native app matches the web app's theme for the account;
  the local default only stands in until it resolves or when the backend is unreachable
  (new Shell/BackendThemeSync.cs, wired in App.OnLaunched; clear _firstThemeApply so the
  backend-driven theme rebuilds the already-constructed page).
- Dashboard: drop the native-only "Personalize TeslaSync" first-run banner and the
  "Tesla account not connected" warning banner — the web shows neither (it surfaces the
  GET STARTED checklist instead) and both read as broken dark-on-light chrome.

Gates: full sln build 0 err/0 warn, dotnet format clean, placeholders 0, 31537 tests pass.
Verified via live screenshots against http://localhost:3000.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…parity)

The web app reads the account's unit preferences from the backend /settings document and
renders mi/mph/°F/psi accordingly; the native app was hard-defaulting to metric, so every
distance/speed/temp read km/°C even when the account is imperial.

- Rename Shell/BackendThemeSync -> BackendSettingsSync and extend it to also map the
  backend unit_of_length / unit_of_temp to the native metric/imperial preference and persist
  it alongside theme + mode (one /settings read seeds all three).
- ShellWindow.ApplySettings now rebuilds the visible page on a units flip (pages resolve
  their unit pref at construction, mirroring web useUnits at render); list pages that already
  subscribe to settings.Changed keep self-applying.
- Pass the resolved unit pref to the dashboard widgets that accept one (vehicle hero, motor,
  charge status, recent drives, analytics summary) so the Command Center renders in-account
  units on first paint.

Gates: full sln build 0 err, dotnet format clean, placeholders 0, 31537 tests pass.
Verified via live screenshot: dashboard now shows mi / °F / Wh/mi matching http://localhost:3000.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add apps/parity/parity-chrome-units.json (the shell/theme/layout units the manifest scan
missed) and merge honest live-visual rows into windows-ledger.json with visualScore + on-disk
shotPath + concrete deltas from real screenshot comparison vs http://localhost:3000:

- done (visual >= 95): component:dashboard/Banners, component:units/BackendSync
- todo (recorded score + deltas): component:shell/Sidebar (88), component:theme/BackendSync (92),
  component:shell/TopToolbar, component:shell/StatusBar, component:dashboard/LayoutSystem,
  component:data-display/DigitalTwin3D

Gitignore the apps/windows/.loop-logs/ scratch dir (screenshots are local evidence, not committed).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Map Overview (Live Map) page hard-defaulted to metric, so current speed / location-history
speed / odometer rendered km·h and km while the rest of the app (and the web) showed imperial
for the account. Thread the resolved unit preference into the page so the render boundary
converts to the account units.

- MapOverviewPage gains an optional units ctor arg passed through to its view-model (defaults
  to metric, so the parameterless/test ctors are unchanged).
- The shell LiveMap factory passes AppSettingsHost.Current.ToUnitPref(); ApplySettings already
  rebuilds the page on a units flip, so it stays in sync.

Gates: full sln build 0 err, dotnet format clean, 31537 tests pass.
Verified via live screenshot: Live Map now shows mph / mi matching http://localhost:3000.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Climate Control page was registered with the 2-arg ctor that hard-pins UnitPref.Metric, so
inside/outside/set temperatures rendered in °C while the rest of the app (and the web) used the
account's imperial preference. Pass AppSettingsHost.Current.ToUnitPref() to the 3-arg ctor.

This completes the units sweep for data-wired pages: the Drives/Charging/Trips/Vehicles list pages
self-subscribe to settings; the dashboard widgets, Live Map and Climate are now passed the pref.
(FleetCompare/Glance/TripPlanner/TripReplay/WatchFace are registered with empty/noop sources — they
render no live data, so units are moot there; that is a separate data-wiring gap, not a units bug.)

Gates: full sln build 0 err, dotnet format clean, 31537 tests pass.
Verified via live screenshot: Climate Control now shows °F matching http://localhost:3000.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…units

Most data-backed pages were registered without an explicit UnitPref, so their ViewModels fell back to
"units ?? UnitPref.Metric" and rendered km / Wh-per-km / per-km while the account (and the web) is
imperial -- e.g. the Statistics page showed 78 km and Wh/km. Only the list pages (which self-subscribe to
settings) and the two pages I wired by hand (Live Map, Climate) were correct.

Systemic fix (web useUnits() parity) instead of threading units through ~40 page ctors + shell registrations:
- New App.Core UnitPrefAmbient.Current (defaults to UnitPref.Metric).
- ShellWindow publishes it from the account preference at startup and on every settings change, before the
  page rebuild -- so a recreated page renders in the new units.
- Swap the 166 production "?? UnitPref.Metric" fallbacks (144 files: pages, projections, sections/panels/
  cards, dashboard widget VMs, FormattedValues, TsVehicleHeroCard) to "?? UnitPrefAmbient.Current". Explicit
  units still win where passed; only the omitted-units path changes. Test fallbacks are untouched, and no
  test mutates the ambient, so the 31537 tests keep their deterministic metric default.

Gates: full sln build 0 err, dotnet format clean, 31537 tests pass.
Verified via live screenshot: Statistics (never edited individually) now renders 48 mi and Wh/mi matching
http://localhost:3000. Known follow-up: a few hardcoded per-km labels (e.g. "Cost per km") still need the
unit label -- the values already convert.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…count units

The Driving Coach section hard-coded Wh/km efficiency labels/values and a per-drive "km" distance, so on an
imperial account the per-drive table read e.g. "Wh/km" / "156" / "24 km" while the rest of the page showed
mph/degF. The values were never converted because BuildCoach/BuildPerDrive did not receive the unit pref.

- New tested converter UnitConverters.EfficiencyFromWhPerKm (Wh/km -> Wh/mi = x metres-per-mile/metres-per-km)
  + UnitLabels.EfficiencyLabel, with EfficiencyConverterTests (identity, 150 -> 241.4016 Wh/mi, labels).
- Thread the UnitPref through BuildCoach + BuildPerDrive; convert avg/best efficiency, the per-drive
  efficiency value, the per-drive distance (km -> DistanceFromSi via metres), and make the efficiency column
  header unit-aware.

Gates: full sln build 0 err, dotnet format clean, 31543 tests (+4) pass.
Verified via live screenshot: per-drive table now shows "Wh/mi" / 251 / "1 mi" matching the imperial account.
This establishes the shared converter the remaining hardcoded-label sites can adopt.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants