Skip to content

[Telemetry] Reconsider device_name denormalization on telemetry tables #274

Description

@KacperKozak

Question

Should device_name be dropped from the telemetry tables, keeping only a device/board identifier?

Raised while adding updated_at sync cursors (PR #273 on KacperKozak/vescape). Not actioned — needs a decision on history semantics first.

Findings from the codebase

The naming is misleading. There is no board_name or board_id on telemetry. The columns are:

device_id   = BLE id         (SessionConfigBuilder.kt:36  deviceId = bleId)
device_name = board nickname (                            deviceName = boardName)

CONTEXT.md:378 already flags this: "device" is ambiguous, resolved term is Board. These columns predate that resolution.

Four tables carry device_name: telemetry_frames, telemetry_minute_buckets, telemetry_markers, diagnostic_events.

It is live, not dead code. Four display consumers:

where renders
src/screens/main/history/HistoryTelemetryPanel.tsx:512 ride title meta via formatRideMeta
src/modules/history/components/HistorySessionSheet.tsx:129 session list row
src/modules/history/lib/historyMapMarkerInfo.ts:81 Board: <name> in marker callout
src/app/settings/eventLog.tsx:101 diagnostic event meta line

Never filtered, grouped, or ordered on — pure display payload. device_id is a query key (bucket composite PK, marker/frame WHERE clauses).

Why it is not a clean delete

Deriving the name at read time means joining boards.ble_id = telemetry.device_id. ble_id is not a stable identity:

  • nullable (unlinked boards)
  • mutable — re-linking a board to a different peripheral orphans its old telemetry
  • deleting a board wipes the label from past rides; today they keep the name the board had at ride time
  • renaming a board retroactively relabels history

docs/adr/0005-ride-history-read-paths-stay-precomputed.md also states history reads stay precomputed and must not reconstruct on read.

So the current denormalization may be deliberate: a durable historical label that survives rename and delete.

Options

  1. Drop from telemetry_frames only. That is where the cost actually is — one row per sample at up to 20 Hz, each repeating the name string. Buckets/markers/diagnostic_events are low-cardinality and the column is nearly free there, and they are the actual display sources. Needs confirming that the frames value at TelemetryRepository.kt:938 (frame.deviceName ?: base?.deviceName) is always overridden downstream and never surfaces.
  2. Add a real board_id FK to telemetry, backfilled by matching ble_id -> boards, and keep device_name as the historical label. Gives sync a stable board identity instead of a BLE id. Bigger migration, with unresolvable rows for deleted or re-linked boards.
  3. Leave it. The column earns its keep as a durable label; rename to board_name/board_id for glossary alignment if anything.

Option 2 interacts with the incremental-sync work: syncing telemetry keyed on a mutable BLE id is likely wrong for the server regardless of the device_name question.

Likely files

  • modules/vescape-core/android/src/main/java/expo/modules/vescapecore/telemetry/TelemetryEntities.kt - the four Room entities carrying device_name
  • modules/vescape-core/android/src/main/java/expo/modules/vescapecore/telemetry/TelemetryRepository.kt - write + reconstruction paths, incl. line 938
  • modules/vescape-core/android/src/main/java/expo/modules/vescapecore/connection/SessionConfigBuilder.kt - where deviceId = bleId / deviceName = boardName originate
  • modules/vescape-core/ios/telemetry/TelemetryDatabase.swift - iOS DDL for the same four tables
  • modules/vescape-core/ios/telemetry/TelemetryDao.swift - iOS frame/bucket/marker writes
  • src/modules/history/lib/sessions.ts - HistorySession.deviceName, the main read shape
  • docs/adr/0005-ride-history-read-paths-stay-precomputed.md - constraint on history read paths

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:dbTouches database / persistent storagearea:nativeTouches native side (modules/vesc-ble, Swift/Kotlin)area:telemetryLive telemetry ingest and displaycomplexity:mediumNeeds care, moderate integration surface. Use sonnet.needs-triageMaintainer needs to evaluate this issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions