wiki: confirm SPA implements IMEI join per WS contract
Adds an explicit SPA-side join section in position-record.md and references the implementation file (src/data/devices.ts -> useDevicesByImei) from the deviceId field row in the WS contract page. Captures the brief drift-and-realign episode where the SPA was keying by uuid before Phase 3.4 and the device list panel rendered id prefixes. The contract itself didn't change - the SPA implementation just caught up with what the wiki already said.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
title: Position Record
|
||||
type: concept
|
||||
created: 2026-04-30
|
||||
updated: 2026-05-03
|
||||
updated: 2026-05-04
|
||||
sources: [gps-tracking-architecture, teltonika-ingestion-architecture, teltonika-data-sending-protocols]
|
||||
tags: [data-model, boundary-contract]
|
||||
---
|
||||
@@ -94,4 +94,17 @@ Why store the IMEI rather than the uuid:
|
||||
- [[tcp-ingestion]] writes positions without any business-plane round-trip ([[plane-separation]]), so the only identifier it has at write time is the IMEI.
|
||||
- Devices can move between `entry_devices` rows across events; positions are an immutable per-IMEI record.
|
||||
|
||||
If/when a Phase 2 redesign moves to uuid-keyed positions, this is the section to revise — and `processor` `src/live/snapshot.ts` + `src/live/device-event-map.ts` both lose the translation hop.
|
||||
If/when a Phase 2 redesign moves to uuid-keyed positions, this is the section to revise — and `processor` `src/live/snapshot.ts` + `src/live/device-event-map.ts` both lose the translation hop, alongside `react-spa`'s `src/data/devices.ts` (`useDevicesByImei` becomes `useDevicesById`).
|
||||
|
||||
### Consumer-side join (SPA)
|
||||
|
||||
The same translation hop applies in [[react-spa]] when the live channel's `position.deviceId` (IMEI) needs to resolve to a Device row's `model` / `serial_number` / vehicle / crew metadata. Implementation:
|
||||
|
||||
```ts
|
||||
// src/data/devices.ts
|
||||
export function useDevicesByImei() {
|
||||
// readItems('devices') -> Map<imei, Device>
|
||||
}
|
||||
```
|
||||
|
||||
Used by `<MapPositions>`, `<MapTrails>`, and `<DeviceListPanel>`. Briefly drifted to keying by `devices.id` (uuid) between Phase 2 and Phase 3.2 — surfaced as device labels rendering 8-char id prefixes ("35042406") instead of model + IMEI tail ("FMB920 #3619"). Re-aligned with this contract on 2026-05-04 before Task 3.4's per-device detail panel started consuming the join.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
title: Processor WebSocket contract
|
||||
type: synthesis
|
||||
created: 2026-05-02
|
||||
updated: 2026-05-03
|
||||
updated: 2026-05-04
|
||||
sources: [gps-tracking-architecture, traccar-maps-architecture]
|
||||
tags: [websocket, protocol, contract, telemetry-plane, decision]
|
||||
---
|
||||
@@ -161,7 +161,7 @@ Field semantics:
|
||||
|---|---|---|---|
|
||||
| `type` | `"position"` | yes | Discriminator. |
|
||||
| `topic` | string | yes | Echoes the subscription. Allows multiplexing on one connection. |
|
||||
| `deviceId` | string | yes | **Phase 1: the IMEI** (vendor identifier, e.g. `"350424064163619"`) — same value as `Position.device_id` per [[position-record]]. Originally specified as `devices.id` (uuid) here; the implementation diverged because [[tcp-ingestion]] only knows the IMEI at write time and the live channel ships the same identifier through end-to-end. SPA joins `deviceId` → `devices.imei` to look up entry/vehicle/crew via TanStack Query against [[directus]]. Closing this divergence (uuid on the wire) is a Phase 2 question; not blocking dogfood. |
|
||||
| `deviceId` | string | yes | **Phase 1: the IMEI** (vendor identifier, e.g. `"350424064163619"`) — same value as `Position.device_id` per [[position-record]]. Originally specified as `devices.id` (uuid) here; the implementation diverged because [[tcp-ingestion]] only knows the IMEI at write time and the live channel ships the same identifier through end-to-end. SPA joins `deviceId` → `devices.imei` to look up entry/vehicle/crew via TanStack Query against [[directus]]. Consumer-side implementation lives in [[react-spa]] at `src/data/devices.ts` (`useDevicesByImei()` — builds `Map<imei, Device>`); used by `<MapPositions>`, `<MapTrails>`, and `<DeviceListPanel>` for label / metadata lookup. Closing this divergence (uuid on the wire) is a Phase 2 question; not blocking dogfood. |
|
||||
| `lat` / `lon` | number (degrees, WGS84) | yes | GPS coordinates. **Coordinate order in JSON is `lat`/`lon`** (not `[lon,lat]` GeoJSON ordering — that conversion happens in the SPA). |
|
||||
| `ts` | number (epoch milliseconds, UTC) | yes | Authoritative timestamp from the device's GPS fix. **Always use this, never `Date.now()` on the client.** |
|
||||
| `speed` | number (km/h) | optional | Omitted if device reports speed=0 with invalid GPS fix (per [[teltonika]] convention). |
|
||||
|
||||
Reference in New Issue
Block a user