# 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?