8.3 KiB
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-11andapp/features/page.tsx:15-20useMath.randomfor 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 bytests/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/portalis 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 fromusers/{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-ridesdiscovery + FirestoreonSnapshot; create/edit/delete/join/leave write togroup_rides. 🟠 join/ride identifier generated client-side withMath.random(:1008) — weak/non-authoritative; 🟠INITIAL_GROUP_RIDESseeds 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 Firestorelive_presencewith authorization + loading + error states and no fixture fallback;INITIAL_RADAR_RIDERSis 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.tsxis one static hero +mailto:. No public ticket backend exists (theapi/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.randomcounters (label as demo), hardware roadmap labelling.
Open product questions (do not block P0/P1 truthfulness fixes)
- Support: confirm no public ticket backend is planned for this release (default: email + FAQ).
- Device-connections block: remove, or convert to a truthful "manage in mobile app" state?
- Club routes/chat empty states: plain empty state, or keep clearly-labelled "example" content?