feat(map): position-history markers at every fix, points-only mode, hover tooltip (#3492)#3495
Conversation
…over tooltip (#3492, #3494) Three improvements to the position-history map layer (closes the duplicate #3494 too): 1. Bug: a marker at EVERY fix. Previously a fix only rendered a marker when its packet carried heading data (a rotated triangle); fixes without heading drew nothing — the line connected invisible vertices. Now every fix renders a CircleMarker dot; the heading triangle is overlaid (non-interactive) only when heading is present. 2. Feature: "Points only (no line)" Map Features toggle. New per-user map preference (MapContext + user_map_preferences.position_history_points_only, migration 090) that, when on, omits the connecting Polyline and shows only the per-fix dots. 3. Feature: hover tooltip per fix showing timestamp, hop count, and SNR — SNR only when the fix was heard directly (hopStart === hopLimit, i.e. 0 hops). To support this, per-position-fix receive metadata is now captured going forward: telemetry gains rxSnr/hopStart/hopLimit columns (migration 089), populated on the lat/lon rows at ingest and surfaced per fix by the position-history API. Fixes received before upgrading show the timestamp only (capture-forward). Note: drizzle-orm references all schema-defined columns on insert/select, so the manual telemetry-table CREATE statements in repo tests were updated to include the new columns. Tests: every-fix dot + no-heading dot + cap (mapHelpers), points-only column mapping (misc.mapprefs), SNR/hop capture round-trip (telemetry.extra), migration registry count 90. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job PR Review
Overall this is a well-constructed PR. The architecture is sound, the migrations are idempotent across all three backends, and the feature is cleanly decomposed. A few things worth discussing before merge: Potential Issues1.
|
…b test table The PG path of telemetry.multidb.test.ts (run in CI, skipped locally) creates its own telemetry table; it needs the #3492 columns too since drizzle references all schema columns on insert. SQLite path was already updated.
|
Claude finished @Yeraze's task —— View job PR Review
Overall this is a well-structured PR. The architecture is clean, the migrations are idempotent across all three backends, and the three features (bug fix + points-only mode + hover tooltip) are well-decomposed. Here's the full review: Potential Issues1.
|
…ection B2, part 1) (#3498) * refactor(test): shared createTestDb helper from the migration registry (section B2, part 1) ~40 non-migration test files hand-roll `CREATE TABLE` per backend, duplicating src/db/schema. That DDL drifts: a schema column-add breaks N tests, and the PG/MySQL copies (only run in CI) diverge silently — exactly what broke #3495. Add src/server/test-helpers/testDb.ts: `createTestDb()` runs the REAL SQLite migration registry (baseline 001 + every ALTER) against a fresh `:memory:` database, so each test gets the exact production schema and a schema change is a single edit. Includes a smoke test asserting key tables and recent columns (telemetry.rxSnr from migration 089) are present and a repo round-trip works. Migrate the three SQLite-only telemetry repo tests — the ones whose hand-rolled telemetry DDL had to be patched for #3492/#3495 — to use the helper: telemetry.test.ts, telemetry.extra.test.ts, telemetry.badTimestamp.test.ts. This is part 1: the helper is proven and the most-recently-fragile DDL is gone. The remaining ~37 hand-rolled tables (nodes in ~20 files, etc.) will be migrated incrementally in follow-ups using this now-proven helper. telemetry.multidb.test.ts is intentionally left — it deliberately exercises per-backend DDL. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(test): address review — drop redundant dedupe-index DDL, document cast claude-pr review on #3498: the 'duplicate packet dedupe' block in telemetry.test.ts still manually created telemetry_source_packet_type_uniq, now dead DDL since createTestDb() applies migration 032. Removed it (test still passes, confirming the index comes from the migration). Also documented the as-any cast in testDb.ts per the review. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Closes #3492 and #3494 (duplicate).
Three improvements to the position-history map layer.
1. Bug — a marker at every fix
Position history previously rendered a marker only where a fix's packet carried heading data (a rotated
▲); fixes without heading rendered nothing — the line connected invisible vertices. Now every fix renders aCircleMarkerdot, and the heading triangle is overlaid (non-interactive) only when heading is present. The last no-heading point (which was skipped entirely) now shows too.2. Feature — "Points only (no line)" toggle
A new Map Features checkbox (shown under Show Position History) hides the connecting line and shows only the per-fix dots. Persisted per user via a new
user_map_preferences.position_history_points_onlycolumn (migration 090) wired throughMapContext→/api/user/map-preferences.3. Feature — hover tooltip (timestamp, hops, SNR)
Each fix now has a hover tooltip with the timestamp, hop count, and SNR — only when the fix was heard directly (
hopStart === hopLimit, i.e. 0 hops; relayed fixes omit SNR since it isn't meaningful).This required capturing data that wasn't stored before: the
telemetrytable gainsrxSnr/hopStart/hopLimitcolumns (migration 089), populated on the lat/lon rows at ingest from the receiving packet, and surfaced per fix by the position-history API andPositionHistoryItem. Capture-forward: only fixes received after upgrading have SNR/hops; older fixes show the timestamp only and the tooltip omits the missing parts gracefully.Notes
CREATE TABLE telemetrystatements in the repo unit tests were updated to include the new columns (verified the behavior with a minimal repro before mass-editing).Tests
mapHelpers: dot at every fix incl. no-heading, triangle only when heading, point cap, empty input.misc.mapprefs:positionHistoryPointsOnly→position_history_points_onlycolumn mapping (3 backends).telemetry.extra: rxSnr/hopStart/hopLimit capture round-trip viagetPositionTelemetryByNode.migrations: registry count 90, last =add_position_points_only_to_map_prefs.Validation
tsc --noEmit: clean🤖 Generated with Claude Code