fleet-platform/db/migrations/20260601000023_position_history_dedup.sql
kianiadee 84e9421b4d
Some checks are pending
build / lint-test (push) Waiting to run
build / build-push (push) Blocked by required conditions
Self-host MapLibre; de-dupe position_history
- Vendor maplibre-gl 4.7.1 (js+css) and serve from /vendor instead of the unpkg CDN — no external dependency/SRI gap for the core map.

- Projector skips duplicate (imei, occurred_at) history rows via NOT EXISTS (parked devices re-report the same gpsTime each poll); migration 23 dedupes existing rows and adds a unique index.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 03:41:34 +03:00

32 lines
1.3 KiB
SQL

-- migrate:up
--
-- One-time cleanup + guard for state.position_history duplicates.
--
-- A parked device re-reports the same gpsTime on every 60s poll, so before the
-- projector's write-time NOT EXISTS guard (shipped alongside this migration)
-- the history hypertable accumulated identical (imei, occurred_at) rows —
-- bloating storage and inflating the "fix count" shown in the trip dock.
--
-- Step 1 delete duplicates, keeping the lowest history_id per
-- (imei, occurred_at).
-- Step 2 add a unique index so duplicates can never reappear. It includes
-- occurred_at (the hypertable partition column), which TimescaleDB
-- requires for a unique index on a hypertable.
--
-- NOTE: the DELETE scans the whole hypertable; run it in a quiet window. The
-- migration is independent of the projector deploy order — the code's
-- NOT EXISTS guard needs no constraint, so applying this before/after a
-- redeploy is both safe.
DELETE FROM state.position_history a
USING state.position_history b
WHERE a.imei = b.imei
AND a.occurred_at = b.occurred_at
AND a.history_id > b.history_id;
CREATE UNIQUE INDEX IF NOT EXISTS position_history_imei_occurred_uq
ON state.position_history (imei, occurred_at);
-- migrate:down
DROP INDEX IF EXISTS state.position_history_imei_occurred_uq;