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:
parent
3cd8bbefa3
commit
4eb2075c7a
|
|
@ -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.
|
||||||
Loading…
Reference in New Issue