MotorSignal-App/website/docs/WEBSITE_FEATURE_AUDIT_2026-...

8.3 KiB
Raw Permalink Blame History

MotorSignal Website — Feature Audit Matrix

Date: 2026-10-14 Branch: fix/website-production-hardening-20261014 Baseline: PR #36 integration HEAD 4931920 (codex/master-consolidation-20261012) Scope: website/ only (Next.js 16.3.4 / React 19). Flutter, Drift, Firebase rules, Cloudflare Worker, and backend production code are out of scope.

Method: classifications below are grounded in the current source (file:line evidence), not in filenames or prior docs. "Verified truthful" means the code was read and does a real backend operation (or honestly reports unavailability); it does not claim any live device / motorcycle validation.

Legend — status: ✅ implemented & truthful · 🟠 partial · 🔴 broken / misleading · 🏷️ UI-only placeholder · 🔌 backend-dependent · 🗓️ deferred/roadmap. Severity: P0 security / data-integrity / misleading success · P1 broken core workflow · P2 incomplete / usability · P3 roadmap.

Summary

The PR #36 baseline is substantially real. Club governance writes, group-ride create/edit/delete/join, the garage/ride-history/export surface, device sessions, the billing-portal fallback, and the Formation Radar are all implemented against real Firestore/API paths or honestly report unavailability. The genuine defects are a focused set of fake success / fabricated-as-real spots plus the static Support page.

# Defect File Severity Status
W1 Rank "permission matrix" faked a save (setTimeout, no write) app/clubs/[clubId]/manage/ranks-roles/page.tsx, components/founder-portal/club-permission-matrix.tsx P0 ✅ FIXED (commit c014c2f)
W-2FA Account shows "Two-Factor Authentication ENABLED" hardcoded for every signed-in user app/account/page.tsx:603-610 P0 🔴 confirmed
W-devices Account shows hardcoded "iOS Mobile App iPhone 16 Pro v4.1.0 · 14m ago" and "Cardo Packtalk Edge · Paired" as real connected devices app/account/page.tsx:463-488 P1 🔴 confirmed
W-routes Club routes: empty Firestore collection falls back to FIXTURE_CLUB_ROUTES (fake "Coastal Marshes" route + /fixtures/routes/*.gpx) in production lib/club-community.ts:265-268 P1 🔴 confirmed
W-chat Club chat: empty channel falls back to FIXTURE_CHAT_MESSAGES in production lib/club-community.ts:443-447 P1 🔴 confirmed
W-metrics Account dashboard metrics initialises to fabricated 12480 mi / 184 rides / 56.4° before real data loads (persists if load fails) app/account/page.tsx:25 P2 🟠 confirmed
W2 Support Center is a static hero + mailto: only — no FAQ, no validation, no ticketing app/support/page.tsx P2 🔴 confirmed
W-deadctl Dead/no-op controls: "Change" (telemetry privacy), "Manage Devices", "Security Logs"→/account, static "All Synced" app/account/page.tsx P2/P3 🟠 confirmed

Feature matrix (by area)

Public site & navigation

  • Homepage app/page.tsx + components/landing/* — ✅ marketing content.
    • 🟠 components/landing/TelemetryStrip.tsx:10-11 and app/features/page.tsx:15-20 use Math.random for animated counters. Decorative marketing, not presented as a user's real telemetry. P3 — acceptable but worth a "demo" label.
  • Navigation / responsive mobile nav app/layout.tsx — ⏳ not yet width-tested (Phase 8).

Authentication & account

  • Login / register / forgot-password / verify-email — ✅ real (components/auth-form.tsx, api/auth/[action]); covered by tests/auth-form.test.tsx, auth-recovery-verification.
  • Account settings app/account/page.tsx — ✅ mostly real, with the W-2FA / W-devices / W-metrics / W-deadctl defects above.
  • Device sessions app/account/page.tsx + api/account/sessions — ✅ real list, revoke & revoke-all, pagination, truthful empty/loading states.
  • Subscription & billing — ✅ truthful: /api/billing/portal is unconfigured and the page says so ("managed through the mobile app"); no fake success (app/account/page.tsx:107-141).

Garage & motorcycle management

  • components/app-cloud-data.tsx — ✅ real Firestore: add / edit / delete / make-primary / photo upload (users/{uid}/motorcycles), image via /api/motorcycle-image.

Ride history, telemetry sessions & export

  • components/app-cloud-data.tsx — ✅ real rides from users/{uid}/rides, GPX & CSV export handlers, delete, "Show more" pagination. CSV/GPX byte-integrity not yet re-verified (Phase 4/9).
  • Telemetry Forensic Replay components/web-telemetry-replay-modal.tsx — ⏳ not yet fully audited (map tiles, progress, playback smoothness — Phase 4). Tests exist (tests/telemetry-replay-export.test.tsx, replay-recorded-data.test.tsx).

Clubs / Founder Portal

  • Profile / access-settings / ownership-transfer / archive — ✅ real writes with owner/admin authorization (lib/club-data.ts; demo branch uses labelled simulated latency only).
  • Applications approve/decline — ✅ real transactional writes.
  • Member rank assignment — ✅ real (updateMemberRank).
  • Rank permission matrix — ✅ FIXED (W1): now a truthful read-only reference.
  • Club routes — 🔴 W-routes fixture fallback.
  • Club chat / wall — 🔴 W-chat fixture fallback (wall send path not yet fully audited).

Group Rides

  • Public page app/group-rides/page.tsx — ✅ splits by auth: signed-out → GroupRidesShowcase (clearly labelled "Sample Pack Formations" / "Radar Simulation"), signed-in → GroupRidesManagement. Public path exposes no real private rides.
  • Authenticated Hub components/group-rides/group-rides-management.tsx — ✅ real: /api/group-rides discovery + Firestore onSnapshot; create/edit/delete/join/leave write to group_rides. 🟠 join/ride identifier generated client-side with Math.random (:1008) — weak/non-authoritative; 🟠 INITIAL_GROUP_RIDES seeds initial state (replaced on first snapshot; can linger if no Firestore). P2.
  • Address autocomplete / route distance / scheduling / join codes / QR — ⏳ not yet fully audited (Phase 3).

Live Formation Radar

  • components/group-rides/live-pack-radar.tsx — ✅ truthful. Real rides subscribe to Firestore live_presence with authorization + loading + error states and no fixture fallback; INITIAL_RADAR_RIDERS is used only for the showcase/demo and is explicitly labelled "Public Demonstration (Simulated Pack)" with "[Simulation Demo]" ping copy. The historical dummy-data concern is already remediated in this baseline.

Device connections / hardware

  • 🔴 W-devices: account "App Connections" block hardcodes a connected iOS app and a paired Cardo unit. Apple Watch row is truthful ("Not Connected (Unavailable on Web)").
  • Helmet Comms / GoPro / Apple Watch as first-class features — 🗓️ roadmap; must be labelled.

Support Center

  • 🔴 W2: app/support/page.tsx is one static hero + mailto:. No public ticket backend exists (the api/ops/support/tickets/* routes are the internal operations console, not a public endpoint). Phase 6 remediation: keep email fallback, add grounded FAQ + validated contact UX; do not simulate ticket submission.

Operations console (app/api/ops/*, components/ops/*, app/admin)

  • Out of the brief's feature list; appears to be a separate internal console. Not modified.

Remaining P0–P3 work (website)

  • P0 — W-2FA (false security state). Fix: show real MFA state / "managed in mobile app", never a hardcoded "ENABLED".
  • P1 — W-devices, W-routes, W-chat (fabricated-as-real). Fix: real state or truthful empty/unavailable; never fixtures in production paths.
  • P2 — W2 Support (FAQ + validation, email fallback), W-metrics (init to loading/0), W-deadctl (wire or remove dead controls), group-ride client-side id generation, mobile responsiveness pass (Phase 8), telemetry replay deep audit (Phase 4).
  • P3 — marketing Math.random counters (label as demo), hardware roadmap labelling.

Open product questions (do not block P0/P1 truthfulness fixes)

  1. Support: confirm no public ticket backend is planned for this release (default: email + FAQ).
  2. Device-connections block: remove, or convert to a truthful "manage in mobile app" state?
  3. Club routes/chat empty states: plain empty state, or keep clearly-labelled "example" content?