Commit Graph

42 Commits

Author SHA1 Message Date
Developer dd35b216d1 fix(website): persisted-only ride creation and reconciled replay timing (PR #38 hardening)
Phase 1 — group ride creation (no phantom rides):
- Check authentication and Firestore availability BEFORE touching UI state; an unauthenticated
  user (or unavailable Firestore) now gets an actionable error and no phantom ride, instead of a
  local entry that was never saved.
- Insert the ride into UI state ONLY after batch.commit() confirms the write; on commit failure
  nothing is inserted and an error is shown.
- Prevent duplicate submissions: the create modal disables its submit button while in flight, and
  the hub guards with a ref.
- The join code remains the real Firestore document id (no fabricated ids).
- Extract commitGroupRide (pure, dependency-injected) so every path is unit-testable.

Phase 2 — replay playback timing:
- The elapsed clock and rider marker both derive from the same cursor, so they cannot drift.
- Manual seeks (scrub, restart, corner jump, arrow keys) go through seekTo(), which reconciles
  playback timing (clears carry/last-frame) so no stale budget is applied after a seek.
- Make gap compression explicit: a caption labels the timeline as recorded elapsed time and warns
  that dead time in multi-segment recordings is skipped during playback.

Tests: commitGroupRide (unauthenticated / unavailable / commit-ok / commit-failed); group-rides
hub now uses an authenticated mock with deterministic Firebase — authenticated create persists,
unauthenticated create is blocked with no phantom, a failed commit leaves no phantom, and the
create modal blocks duplicate submits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 13:12:49 -04:00
Developer 6956e809a3 fix(website): truthful group-ride creation — no false success, no fabricated GPS (Phase 3)
Creating a ride from the hub had two integrity problems:
- The "Created … success" toast fired optimistically before the Firestore write, and a
  commit failure was only console.error'd — so a user could be told the ride was created
  when nothing persisted (the ride would then vanish on the next snapshot).
- Every created ride wrote a hardcoded meetingPoint at 34.5378, -83.9849 (Helen, GA)
  regardless of the typed location — fabricated GPS attached to real rides.

Fixes:
- Report success only after `batch.commit()` resolves; on failure, roll back the optimistic
  insert and show an error. When there is no authenticated session / Firestore, keep the
  local entry for responsiveness but make no cloud-success claim.
- Extract buildWebGroupRidePayload (pure): stores the rally point as displayName/address
  text and omits latitude/longitude (the web form has no map picker / geocoder, so we never
  fabricate coordinates). mapFirestoreRideToSummary already treats a missing coordinate as
  "not pinned yet".

Join-by-code, join/leave, edit, and delete flows were reviewed and persist/authorize
correctly; no changes needed there.

Tests: buildWebGroupRidePayload asserts no fabricated lat/lon, rally-point text/fallback,
authoritative organizer/access fields, scheduled-time handling, and club identity. Existing
group-ride UI tests remain green.

Known limitation: true address autocomplete and automatic route-distance calculation require
a geocoding/routing API that does not exist in this codebase; distance and rally point remain
free-text until that backend lands.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 12:49:16 -04:00
Developer ae1980b4ed fix(website): synchronize telemetry replay playback with recorded time (Phase 4)
The replay loop advanced the cursor by one sample every 50 ms / speed, assuming a uniform
20 Hz stream. Recorded telemetry is not always uniform (segment breaks and GPS-loss gaps up
to 5 s), so the rider marker drifted out of sync with the elapsed-time readout — which is
derived from real timestamps — and "1x" did not match real time across gaps.

Make playback timestamp-driven:
- Add advancePlaybackIndex(points, fromIndex, budgetMs): a pure helper that consumes a
  budget of virtual recorded time, advancing by the real delta between samples so the
  marker tracks the elapsed-time clock. Disconnected transitions (per
  areTelemetryPointsConnected) are compressed to a single 50 ms step so playback never
  stalls across multi-second dead time. No coordinates are altered.
- Drive the rAF loop with frameDelta * playbackSpeed plus carry-over, resuming from an
  index ref so manual scrubs are honored.

Verified sound without changes: SHA-256-checked R2/inline telemetry load, CSV/GPX parse and
export integrity, loading/error/empty overlays, and tile-provider fallback.

Tests: advancePlaybackIndex covers uniform cadence, carry-over, gap compression, end-clamp,
and empty input. Existing replay/export/corner tests remain green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 12:36:07 -04:00
Developer 3cd8bbefa3 feat(website): grounded FAQ and validated contact on Support Center (W2)
The Support page was a single static line plus a mailto link. There is no public
ticket backend (only the internal ops console), so rather than simulate ticket
submission, improve the page truthfully:
- Add an FAQ grounded in features that actually ship (offline recording/sync,
  billing + 2FA managed in the mobile app, GPX/CSV export, session revocation,
  radar live-presence rules, public vs authenticated group rides).
- Add a validated contact form (name/email/topic/message) that opens a prefilled
  email in the visitor's own client. It never claims a ticket was filed and states
  plainly that the message is not sent until the visitor sends it.
- Keep support@motorsignal.app as the real, working fallback channel.
- Preserve the existing public-page visual system (content-page / eyebrow / faq-section).

Tests: FAQ + real mailto render; invalid input shows validation errors and no
submission claim; valid input opens a mailto (no simulated ticket) with the topic
and email encoded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 12:11:20 -04:00
Developer 2cb3ef9694 fix(website): label fallback club routes and chat as examples (W-routes, W-chat)
When a club has no curated routes or a chat channel has no messages, the data layer
returned fixture content with no indication it was sample data, so riders could mistake
MotorSignal's "Coastal Marshes" route or canned chat messages for their club's real data.

Flag fixture-sourced content and label it in the UI:
- Add isExample to ClubRoute and ChatMessage; set it on every fixture fallback path
  (empty Firestore collection/channel and the dev demo preview).
- Founder Routes: amber "Examples" count, an explanatory banner, and a per-card "Example"
  badge when the routes shown are samples.
- Founder Chat: an "Example thread" pill (instead of "Live Connected") and a banner when
  the only messages are examples, so the header never claims a live conversation that
  does not exist.

Tests: example-labelled routes render the banner/badge/count; example-labelled chat
renders the banner and "Example thread" pill and does not claim "Live Connected".
Existing route/chat tests (real data, no isExample) remain green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 12:08:15 -04:00
Developer c014c2f04f fix(website): stop club rank matrix from faking a permission save (WEB-W1)
The Ranks & Roles "Operational Permission Matrix" previously waited ~400ms and
showed a "Saved" state without persisting anything. No Firestore document, API
route, or security rule stores or enforces a per-rank capability matrix; club
authorization is role-based (Owner/Admin via getPortalPermissions). Persisting
the matrix would require frozen security-rule changes and would create an
unenforced permission model that misleads owners.

Make the control truthful instead of faking success:
- Render the matrix as a read-only reference of the standard governance model
  by default (persistenceAvailable=false): no Save/Reset controls, disabled
  toggles, a "View-only reference" indicator, and a notice stating that access
  is enforced by Owner/Admin roles and per-rank customization is planned.
- Remove the fake setTimeout save handler and the unconditional success state.
- Retain a forward-compatible editable path behind persistenceAvailable for
  when a backend contract ships.
- Document the precise backend contract required to enable persistence.

Tests: read-only matrix renders no Save control, reports no save, and does not
mutate permissions even for Owner/Admin; editable path still fires toggle/save
/reset when persistenceAvailable=true.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 11:20:29 -04:00
Developer 3ba94777a1 fix: resolve Android CI breakpoint overflow and address Codex PR #28 findings
- Fix RenderFlex overflow at short landscape breakpoint (640x320) by scaling center controls in ResponsiveDashboardLayout and clamping LeanAngleIndicator bounds
2026-10-09 18:53:39 -04:00
Developer 20da9ee27d feat(core): reconcile local development, hybrid design, sensor fusion, and docs
- Consolidate Hybrid v1 tokens, theme extensions, and core UI components (HybridCard, HybridMetricTile, HybridRidingActionBar, HybridStaticRecBadge)
2026-10-09 05:12:01 -04:00
Developer c956ffd7bd feat(website): add club curated routes, live squad chat, and portal navigation 2026-10-02 12:39:38 -04:00
Developer 368858670d feat(website): add club moderation, stats, and group rides management 2026-10-02 11:07:44 -04:00
Developer aced2b5435 fix: open club updates from the notification bell 2026-10-01 08:32:06 -04:00
Developer f495ec0cac feat: add club members and wall management 2026-10-01 08:31:45 -04:00
Developer 71cd994b2f feat(mobile): add community social feed, tactical layers, club wall, launch curves, and curvy routes (v1.0.2+102) 2026-09-29 11:50:48 -04:00
Developer 9bc16329ef feat(website): apply stitch tactical design tokens and group ride firestore sync 2026-09-27 07:56:56 -04:00
Developer f20a09addf feat(website): discrete group rides showcase and management architecture lock 2026-09-25 18:36:54 -04:00
Developer 69fefd7b56 feat(website): create separate showcase and management group rides pages 2026-09-25 16:00:47 -04:00
Developer 126f2c6c5f feat(website): add Group Rides Hub navigation links for authenticated riders 2026-09-25 15:35:55 -04:00
Developer 67c25b5c50 feat(website): build interactive group rides hub with live pack radar, filters, and modals 2026-09-25 14:35:58 -04:00
Billie Ponder 1a272ce1ff
fix(ops): decouple action execution to background tasks and stabilize live progress tracking (#24)
Decoupled action execution in FastAPI to background tasks and stabilized live modal progress tracking.
2026-09-22 01:58:53 -04:00
Billie Ponder 54886753b7
feat(ops): add dual speedtest options, support ticket fixes, cms sync, and overview card redesign (#23)
Co-authored-by: Developer <dev@example.com>
2026-09-22 01:38:54 -04:00
Billie Ponder f20c1d13e6
fix(ops): align audit result constraints, action history parsing, and startup reconciliation (#21)
Co-authored-by: Developer <dev@example.com>
2026-09-21 21:28:53 -04:00
Billie Ponder 10d6260393
feat(ops): add live execution progress tracker, stepper, docked hud, and completion modal (#19)
Co-authored-by: Developer <dev@example.com>
2026-09-21 11:04:49 -04:00
Billie Ponder fb67252bc8
feat(ops): add speedtest, cms persistence, support ticket db storage, and action resiliency (#18)
Co-authored-by: Developer <dev@example.com>
2026-09-21 10:46:09 -04:00
Billie Ponder cf7c99b210
feat(ops): implement deployment controls, service restarts, and action auditing (phase 2) (#17)
Co-authored-by: Developer <dev@example.com>
2026-09-21 02:56:58 -04:00
Billie Ponder 0344691194
feat(ops): add disabled action foundation and support report creation (#15)
* feat(ops): add truthful disabled action plane and support modal

* fix(ops): align support report types with backend contract

* fix(ops): address action audit and support validation review

* test(website): add behavioral coverage for support reports

---------

Co-authored-by: Developer <dev@example.com>
2026-09-21 01:19:47 -04:00
Billie Ponder 9d99bfa4e4
feat(ops): implement production operations infrastructure dashboard (phase 1) (#14)
* feat(ops): implement production operations infrastructure dashboard (phase 1)

- Add backend read-only infrastructure metrics collector (CPU, RAM, swap, disk with 80%/90% thresholds, uptime, network cumulative totals, systemd service allowlist) using standard library only (no psutil).

- Register GET /api/v1/ops/infrastructure endpoint guarded by require_ops_roles('operator', 'owner').

- Add Next.js API proxy route /api/ops/infrastructure validating ops session cookie and forwarding to backend.

- Implement dark-surface OperationsInfrastructure component in website admin console with 30s visibility-gated polling and overlap prevention.

- Add comprehensive backend and frontend test suites (8 backend tests, 43 ops-experience tests).

* fix(ops): query internal website version endpoint defensively on verified port 3001

- Query internal website GET /api/version on verified production listener http://127.0.0.1:3001 (configurable via WEBSITE_INTERNAL_URL).

- Parse JSON defensively with a 4096-byte response bound and validate exact 40-char hex revision pattern.

- Add comprehensive tests for valid, missing, malformed, oversized, and unreachable version responses.

- Do not expose internal URLs or connection errors in API responses.

* fix(ops): map postgresql service to cluster unit postgresql@14-main and preserve health errors

- Map public logical service ID 'postgresql' to fixed systemd unit 'postgresql@14-main'.

- Reject direct systemd unit names and arbitrary service names.

- Preserve HTTP 5xx responses as degraded on /api/health before root fallback.

- Add regression tests for postgresql unit mapping, API response name stability, and health 5xx preservation.

---------

Co-authored-by: Developer <dev@example.com>
2026-09-20 17:14:21 -04:00
Billie Ponder da0a05d3a2
fix(website): normalize founder portal page widths across profile, applications, and ranks (#12)
Co-authored-by: Developer <dev@example.com>
2026-09-20 13:46:58 -04:00
Billie Ponder 1a2ac12893
fix(website): expand Founder Portal layout width to fill available canvas (#11)
* fix(website): expand Founder Portal layout width to fill available canvas

* fix(website): restore mobile padding, preserve public main landmark, and harden width test

Apply responsive mobile padding to .site-page-frame under 760px. Render semantic <main> for public routes and <div> for portal routes with internal <main> via SitePageFrame. Assert max-w-[1536px] exclusively and reject old max-w-[1440px] cap in founder-portal.test.cjs.

---------

Co-authored-by: Developer <dev@example.com>
2026-09-20 08:59:43 -04:00
Billie Ponder 59900f46f2
feat(web): add clubs rides management (#9)
Add the disabled Founder Portal Club Rides scaffold aligned with the live GroupRide.clubId domain.

Keep production discovery and actions disabled until a privacy-preserving read path and real management destinations are implemented.
2026-09-20 07:23:00 -04:00
Developer b01054b696 fix(web): repair clubs management experience 2026-09-20 02:02:22 -04:00
Developer d5dcc97495 feat(website): standardize dark glass design system, obsidian contrast buttons, and rider account management 2026-09-18 18:35:31 -04:00
Developer 9418aa2ac8 feat(clubs): add public syndicates directory, club discovery, and founder management portal 2026-09-18 18:35:21 -04:00
Developer fa2fccd137 feat(ops): add incident management, user administration, support tickets, and website CMS 2026-09-18 18:35:12 -04:00
Developer 7365bf56d1 fix: restore website visual assets and shell 2026-09-13 03:45:35 -04:00
Developer cd5201c13a fix: isolate marketing layout checkpoint 2026-09-12 18:36:53 -04:00
Developer bbe6d612a7 fix: repair responsive marketing layouts 2026-09-12 18:16:29 -04:00
Developer 8681e6f259 feat: add Operations incident management 2026-09-10 14:48:08 -04:00
Developer 55b3a5908a feat: add isolated MotorSignal Operations console 2026-09-10 08:17:06 -04:00
Developer 58193f6de4 feat: add founder club applications workflow 2026-09-09 08:37:34 -04:00
Developer d544292a3c feat: add founder club settings and governance lifecycle 2026-09-09 07:51:48 -04:00
Developer 5eb47e8c09 feat: add founder club profile and sub-routing foundation 2026-09-09 07:06:45 -04:00
Developer 912b4d2a45 Improve ride recording and telemetry workflows 2026-09-08 02:13:03 -04:00