docs(website): device-connections backend contract for the full "build real" feed (W-devices)

Documents the blocker: a richer connected-devices panel (platform, app version, last-seen,
accessory pairing) needs a FastAPI endpoint that does not exist yet. Records the proposed
GET /api/v1/account/connections contract and the website wiring to adopt it, and notes what
already shipped truthfully without a backend change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Developer 2026-10-14 12:12:02 -04:00
parent 3cd8bbefa3
commit 4eb2075c7a
1 changed files with 65 additions and 0 deletions

View File

@ -0,0 +1,65 @@
# 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/sessions` feed
(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).
```jsonc
{
"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
1. Add `fetchConnections()` to a lib module, proxied like `/api/account/sessions`.
2. Replace the current heuristic "Authenticated devices" row with the real feed, grouping by
`kind`, showing `label`, `appVersion`, and relative `lastSeenAt`.
3. Add tests for: real feed rendering, empty feed → empty state, and no fabrication when the
endpoint is unavailable.