2.9 KiB
Backend Contract Proposal — Device Connections feed (W-devices)
Status: Partially implemented. The website now shows the device/connection data it can truthfully obtain today. A richer "connected devices" view (platform, app version, last-seen, accessory pairing) needs a backend feed that does not exist yet.
What shipped on the website (no backend change)
The account page "App Connections & Sync" block previously hardcoded a connected iOS app ("iPhone 16 Pro", "v4.1.0", "14m ago") and a paired "Cardo Packtalk Edge". These were fabricated. They are now replaced with truthful, real-data states:
- Google account — reflects the signed-in Firebase user (real).
- Authenticated devices — count comes from the real
/api/account/sessionsfeed (proxied to${MOTORSIGNAL_API_BASE_URL}/api/v1/auth/sessions), already rendered in detail in the Active Device Sessions panel. - Helmet comms & accessories — "Unavailable on web": a browser cannot observe Bluetooth pairing. Managed in the mobile app.
- Apple Watch — "Unavailable on web" (unchanged, already truthful).
Why the full feature needs a backend
A browser cannot see a rider's paired Bluetooth hardware, installed mobile app build, or device platform. Those facts live on the device and in MotorSignal's backend. The auth sessions feed is close but does not classify platform / app version / accessory pairing.
Delivering a true "connected devices" panel therefore requires a backend endpoint (FastAPI; out of scope for the website task and must be authorized separately).
Proposed contract
Endpoint: GET ${MOTORSIGNAL_API_BASE_URL}/api/v1/account/connections
Auth: Bearer access token (same as the sessions endpoint).
{
"devices": [
{
"id": "string",
"kind": "mobile_app | web_session | accessory",
"platform": "ios | android | web | null",
"label": "iPhone 16 Pro", // human-friendly, backend-provided
"appVersion": "4.1.0 | null",
"lastSeenAt": "ISO-8601 | null",
"pairingStatus": "paired | disconnected | null", // accessories only
"current": false
}
]
}
Rules:
- The backend is the only source of platform / app version / accessory pairing. The web client must render exactly what it returns and must never infer or fabricate these.
- Absent/empty feed → truthful empty state ("No linked devices"), never sample data.
- Accessory (Cardo/Sena/GoPro/Apple Watch) rows appear only if the backend reports them; otherwise the web continues to show "Unavailable on web".
Website wiring once the endpoint exists
- Add
fetchConnections()to a lib module, proxied like/api/account/sessions. - Replace the current heuristic "Authenticated devices" row with the real feed, grouping by
kind, showinglabel,appVersion, and relativelastSeenAt. - Add tests for: real feed rendering, empty feed → empty state, and no fabrication when the endpoint is unavailable.