-- Phase 1: remove existing duplicate rows. -- "Duplicate" = same (vehicle_id, category_id, oem_code, name, position). -- Backfill + reactive prefetch can re-drill the same category multiple times; -- without a unique constraint that re-insert kept all rows, leaving 8–34% -- duplicate per source (~108k extra rows of ~588k). Keep the oldest row per -- group (preserves original created_at) and drop the rest. DELETE FROM "parts" WHERE id IN ( SELECT id FROM ( SELECT id, row_number() OVER ( PARTITION BY vehicle_id, category_id, oem_code, name, position ORDER BY created_at ASC, id ASC ) AS rn FROM "parts" ) t WHERE rn > 1 ); --> statement-breakpoint -- Phase 2: prevent future dupes. NULLS NOT DISTINCT (Postgres 15+) so NULL -- position / NULL vehicle_id collapse like equal values rather than each -- counting as a separate "distinct" row. CREATE UNIQUE INDEX IF NOT EXISTS "parts_dedup_idx" ON "parts" (vehicle_id, category_id, oem_code, name, position) NULLS NOT DISTINCT;