240 lines
8.3 KiB
Markdown
240 lines
8.3 KiB
Markdown
# MotorSignal Agent Handoff
|
|
|
|
Last updated: 2026-09-08
|
|
|
|
## Mission
|
|
|
|
MotorSignal is a Flutter motorcycle telemetry app with a Next.js companion website and a FastAPI/PostgreSQL production API. Current work covers the public website, Firebase-linked app data, RBAC/admin operations, and VPS deployment.
|
|
|
|
Workspace:
|
|
|
|
C:\Users\Bill\Desktop\flutter-app
|
|
|
|
Production:
|
|
|
|
Website: https://motorsignal.app
|
|
API: https://api.motorsignal.app
|
|
VPS: motorsignal-admin@89.31.239.10
|
|
|
|
Never put SSH keys, passwords, Firebase private credentials, JWT secrets, SMTP credentials, or database passwords in this file or Git.
|
|
|
|
## Read First
|
|
|
|
1. Root AGENTS.md and its referenced C:\Users\Bill\.codex\RTK.md.
|
|
2. docs/PRODUCTION_DEPLOYMENT_CHECKLIST.md.
|
|
3. docs/WEBSITE_ADMIN_CURRENT_STATE.md.
|
|
4. Relevant docs under docs/agents/.
|
|
|
|
Rules that matter:
|
|
|
|
- Investigate source, callers, schemas, and tests before changing behavior.
|
|
- Do not casually change Flutter telemetry cadence, SensorFusion, RideStateMachine, or Drift schema 7.
|
|
- Preserve the offline-first ride sync pipeline and stable cloud ride IDs.
|
|
- Behavioral changes need focused automated coverage.
|
|
- Preserve unrelated dirty-worktree changes.
|
|
- Do not commit or push without explicit authorization.
|
|
|
|
## Current Local State
|
|
|
|
The worktree is intentionally dirty. Preserve all existing changes.
|
|
|
|
The website currently includes:
|
|
|
|
- Firebase account linking and Firestore app-data display.
|
|
- Password reset, email verification, and session management.
|
|
- RBAC-protected admin console with user, vehicle, ride, and audit views.
|
|
- Stitch-inspired landing page.
|
|
- Completed public Features, Group Rides, Clubs, and Pricing pages.
|
|
- Public menu links for Features, Group rides, Clubs, Pricing, Download, and Support.
|
|
- Hero image at website/public/images/motorsignal-hero.jpg.
|
|
|
|
Important files:
|
|
|
|
website/app/page.tsx
|
|
website/app/features/page.tsx
|
|
website/app/group-rides/page.tsx
|
|
website/app/clubs/page.tsx
|
|
website/app/pricing/page.tsx
|
|
website/app/account/page.tsx
|
|
website/app/admin/page.tsx
|
|
website/app/globals.css
|
|
website/components/site-header.tsx
|
|
website/components/companion-list.tsx
|
|
website/components/app-cloud-data.tsx
|
|
website/components/firebase-link.tsx
|
|
website/components/session-manager.tsx
|
|
website/lib/firebase-client.ts
|
|
|
|
The latest public-page source is newer than the deployed bundles. Build and package it before deploying.
|
|
|
|
## Stitch Reference Assets
|
|
|
|
Downloaded under stitch/admin-dashboard-revamp/:
|
|
|
|
- flagship-landing/
|
|
- features-telemetry-architecture/
|
|
- group-rides-pack-radar/
|
|
- clubs-fleet-intelligence/
|
|
- pricing-hardware-plans/
|
|
- rider-account-portal/
|
|
- Admin console screenshot and generated HTML
|
|
|
|
These are design references. Do not copy fake Stitch KPI values into production data displays unless labeled illustrative. Admin KPIs should come from real API totals.
|
|
|
|
## Firebase Data Contract
|
|
|
|
The Flutter app writes:
|
|
|
|
users/{firebaseUid}/motorcycles/{motorcycleId}
|
|
users/{firebaseUid}/rides/{cloudRideId}
|
|
|
|
Motorcycle fields include year, makeName, modelName, variantName, nickname, and isDefault.
|
|
|
|
Ride fields include startTime, distanceMiles, topSpeedMph, motorcycleYear, motorcycleMake, motorcycleModel, qualityRating, and telemetry bundle metadata.
|
|
|
|
Website AppCloudData reads these owner-scoped collections after Google/Firebase account linking. Firestore rules enforce the Firebase owner UID. Do not merge records using email alone.
|
|
|
|
Firebase project:
|
|
|
|
motoapp-d22e0
|
|
|
|
Backend Firebase linking validates the identity and stores users.firebase_uid. X.509 certificate parsing is fixed and covered by a regression test.
|
|
|
|
## Backend and Production
|
|
|
|
Backend source:
|
|
|
|
backend/motorsignal_api/
|
|
|
|
Important files:
|
|
|
|
backend/motorsignal_api/alembic/versions/e0f5a7123b46_link_firebase_identity.py
|
|
backend/motorsignal_api/tests/test_firebase_auth.py
|
|
backend/motorsignal_api/tests/test_api_smoke.py
|
|
|
|
Services:
|
|
|
|
motorsignal-api.service
|
|
motorsignal-website.service
|
|
nginx.service
|
|
|
|
Release layout:
|
|
|
|
/opt/motorsignal/current
|
|
/opt/motorsignal/releases/<release>
|
|
|
|
The API expects /opt/motorsignal/current/app and /opt/motorsignal/current/venv.
|
|
|
|
## Deployment History
|
|
|
|
20260908-06 Account Firestore app-data display
|
|
20260908-07 Stitch-inspired admin console
|
|
20260908-08 First public landing/features/rides/clubs implementation
|
|
20260908-09 Expanded landing page
|
|
|
|
Checksums:
|
|
|
|
20260908-08 website:
|
|
5ab316a7889b76185bee3af86798bf51d22c4dac41907afe27104c0d4d2ea91c
|
|
|
|
20260908-09 website:
|
|
ab561d8974ab10f9f9755c7c54d2df71ea64b4a6e3417d60c0ff112ea10d5f94
|
|
|
|
The latest full Features, Group Rides, Clubs, and Pricing implementation was made after release 09 and has not been packaged. Build a new release, preferably 20260908-10, from the current source.
|
|
|
|
The active VPS release is not confirmed. Check it:
|
|
|
|
readlink -f /opt/motorsignal/current
|
|
|
|
## Deployment Procedure
|
|
|
|
Build:
|
|
|
|
cd website
|
|
npm run build
|
|
|
|
Package the current standalone website:
|
|
|
|
$release='20260908-10'
|
|
$stage="scratch/deploy/$release"
|
|
New-Item -ItemType Directory -Path "$stage/website" -Force | Out-Null
|
|
Copy-Item website/.next/standalone/* "$stage/website" -Recurse -Force
|
|
New-Item -ItemType Directory -Path "$stage/website/.next/static" -Force | Out-Null
|
|
Copy-Item website/.next/static/* "$stage/website/.next/static" -Recurse -Force
|
|
if (Test-Path website/public) { Copy-Item website/public "$stage/website/public" -Recurse -Force }
|
|
Compress-Archive -Path "$stage/website" -DestinationPath "$stage/motorsignal-website-$release.zip" -Force
|
|
|
|
Upload with the existing SSH key:
|
|
|
|
scp -i C:\Users\Bill\.ssh\motorsignal_prod scratch/deploy/20260908-10/motorsignal-backend-20260908-10.zip scratch/deploy/20260908-10/motorsignal-website-20260908-10.zip motorsignal-admin@89.31.239.10:/tmp/
|
|
|
|
Verify SHA-256 on both local and remote files before staging.
|
|
|
|
Root/provider-console cutover:
|
|
|
|
set -euo pipefail
|
|
RELEASE=20260908-10
|
|
DIR=/opt/motorsignal/releases/$RELEASE
|
|
printf 'DIR=%s\n' "$DIR"
|
|
test "$DIR" = "/opt/motorsignal/releases/$RELEASE"
|
|
install -d -o motorsignal -g motorsignal "$DIR"
|
|
unzip -q /tmp/motorsignal-backend-$RELEASE.zip -d "$DIR"
|
|
unzip -q /tmp/motorsignal-website-$RELEASE.zip -d "$DIR"
|
|
ln -sfn backend/app "$DIR/app"
|
|
ln -sfn backend/alembic "$DIR/alembic"
|
|
ln -sfn backend/alembic.ini "$DIR/alembic.ini"
|
|
ln -sfn backend/requirements.lock "$DIR/requirements.lock"
|
|
cp -a /opt/motorsignal/current/venv "$DIR/venv"
|
|
chown -R motorsignal:motorsignal "$DIR"
|
|
ln -sfn "$DIR" /opt/motorsignal/current
|
|
systemctl restart motorsignal-api
|
|
systemctl restart motorsignal-website
|
|
sleep 3
|
|
curl -fsS https://api.motorsignal.app/api/v1/health
|
|
curl -fsS -I https://motorsignal.app/
|
|
curl -fsS -I https://motorsignal.app/features
|
|
curl -fsS -I https://motorsignal.app/group-rides
|
|
curl -fsS -I https://motorsignal.app/clubs
|
|
curl -fsS -I https://motorsignal.app/pricing
|
|
|
|
## Current Deployment Blocker
|
|
|
|
The user reported:
|
|
|
|
ln: failed to create symbolic link '/opt/motorsignal/releases/20260908-08/app/app': File exists
|
|
|
|
This means DIR was likely set one level too deep, ending in /app, or a command was run with an incorrect working directory. The correct target is:
|
|
|
|
/opt/motorsignal/releases/20260908-08/app
|
|
|
|
not:
|
|
|
|
/opt/motorsignal/releases/20260908-08/app/app
|
|
|
|
Always reset and print DIR before symlink commands. Use ln -sfn for known release-local symlinks. Do not recursively delete a release without inspecting it using find, stat, and readlink.
|
|
|
|
## Validation Remaining
|
|
|
|
The latest local website build passed:
|
|
|
|
npm run build
|
|
|
|
Still needed:
|
|
|
|
- Package the latest source as release 20260908-10.
|
|
- Deploy and verify the VPS release.
|
|
- Browser-check the public routes after deployment.
|
|
- Test signed-in Firebase-backed Group Rides, Clubs, and Account data with the real account.
|
|
- Confirm the hero image loads through the standalone bundle.
|
|
- Run the complete Flutter gates before declaring the broader project complete:
|
|
|
|
flutter test
|
|
flutter analyze
|
|
flutter build apk --debug
|
|
|
|
Do not claim Firebase rides exist unless the app has completed cloud sync. Local-only rides will not appear in Firestore.
|
|
|
|
## Git Safety
|
|
|
|
No commit or push was authorized for this handoff. Do not stage the entire repository because it contains unrelated ongoing work. Stage only explicitly requested files if a later user authorizes a commit.
|