-
Notifications
You must be signed in to change notification settings - Fork 1
Telemetry
The Telemetry service owns TrackHub's high-volume, append-heavy data: position fixes, position history, operator sync runs and operator health checks. It stores and serves this data; it never talks to GPS providers — that is the Router's job.
Related pages: Database · Router · Reporting
Telemetry serves the telemetry schema but does not migrate it. The tables are created by the Manager migrations, which is why DB_CONNECTION_TELEMETRY must point at the same TrackHub database.
| Access | Tables |
|---|---|
Read/write (telemetry) |
transporter_position, transporter_position_history, operator_sync_runs, operator_health_checks
|
Read-only (app) |
users, groups, user_group, transporters, transporter_group, transporter_device_assignments, devices, operators, accounts, account_features
|
The read-only app projections exist so the service can enforce account scoping and group visibility without a network hop per request. In production, connect with a role that has read/write on telemetry and read-only on those app tables.
| Entity | Purpose |
|---|---|
| TransporterPosition | The latest-position projection — the freshest fix per transporter. This is what backs the live map. |
| TransporterPositionHistory | The append-only track store, deduplicated by an idempotency key. Used for replay and reporting. |
| OperatorSyncRun | One row per device or position sync attempt, with device and position counts, result and error. |
| OperatorHealthCheck | Operator connectivity and health probe results. |
Operator health is derived, not stored as a rollup. The operator row carries no health columns. Health status and sync summaries are computed at read time from these two tables — which is why every device-sync attempt records an observation, so accounts that only sync manually still get a meaningful Health status.
| Operation | Purpose |
|---|---|
transporterPositionByOperator |
Latest positions for an operator, scoped to the caller's visibility |
transporterPositionsByOperators |
Batched variant — the live-map hot path |
positionHistory |
Stored position history, filtered by account / transporter / device |
positionHistoryRange |
Replay read over a time range (ordered, point-capped), gated by gps.positionHistory
|
operatorSyncRuns |
Recorded sync-run telemetry |
operatorHealth |
Current operator health snapshot, derived from the health-check and sync-run tables |
operatorHealthHistory |
Recent health-check records for an operator |
operatorHealthSummary |
Aggregated uptime, latency and failure counts over a lookback window |
platformSyncActivity |
Platform-wide latest sync/health timestamps for the status page |
| Operation | Purpose |
|---|---|
bulkTransporterPosition |
Upsert the latest-position projection (freshest fix per transporter) |
appendPositionHistory / appendPositionHistoryBatch
|
Append history rows — idempotent, gated by gps.positionHistory
|
persistResolvedAddress |
Write a reverse-geocoded address back onto stored position rows |
recordOperatorSyncRun |
Record a sync attempt |
recordOperatorHealth |
Record an operator health check |
Visibility mirrors the rest of the platform: Administrator and Manager roles read account-wide; other users are scoped to their group membership, resolved through the transporter–group / user–group chain. Service clients read on behalf of already-authorized users.
Feature gating:
| Surface | Gate |
|---|---|
| Latest-position writes, health writes | Core — authorization only |
| History writes and replay reads | gps.positionHistory |
PositionRetentionPurgeService is a hosted service inside the Telemetry web host. It deletes expired history per account, honouring each account's retention days (derived from the gps.positionHistory feature configuration).
It is an on-work-only recorder: an old BackgroundJobRun timestamp is the healthy steady state, not a stuck job.
PlatformSyncActivityReader supports the status page's SyncWorker tile. It is one of two deliberately unscoped readers on the platform — a documented platform-wide read gated by [Authorize(Administrative, Read)]. It returns timestamps and counts only, never an account id.
SyncWorker liveness is derived from data recency, because the worker is a plain Generic Host with no HTTP listener:
| Signal | State |
|---|---|
| Activity within 5 minutes | Up |
No account has gps.integration enabled |
Unknown — "nothing to sync" is not a failure |
| Otherwise | Down |
Telemetry can only see account-level enablement, never per-operator — that lives in Manager, and adding an inter-service call for it was deliberately rejected.
-
attributesis a PostgreSQLjsoncolumn.jsonhas no equality operator, soDistinct(),GroupBy()or set operations over an entity or projection including it fail at runtime with42883. De-duplicate withEXISTSor key-based predicates. EF InMemory does not catch this — only real PostgreSQL does. -
The
extraattribute field is additive and schemaless. New provider signals flow through it with no migration and no cross-service schema change. See Router. - Telemetry has no migrations of its own. Do not add any — the schema belongs to Manager.
Platform
- Architecture
- Technology
- Inter-Service Communication
- Database
- Security and Identity
- User Permissions Overview
Services
- Manager
- Telemetry
- Router
- Adding a Provider
- Geofencing
- Trip Management
- Reporting
- Common Library
- Frontend
Engineering
User docs
- User Guide (ships in the app)