← back to Lifestyle Asset Intel
db/migrations/0002_transactions_unique.sql
36 lines
-- 0002_transactions_unique.sql — idempotent seed.sql + dedupe
--
-- Bug discovered during Max It batch (commit 917d044): re-running
-- db/seed.sql inflated transactions count from 87 → 128 because the
-- table has no natural unique key, so ON CONFLICT clauses are no-ops.
--
-- Fix: dedupe existing rows on the natural key, then enforce it as a
-- UNIQUE constraint going forward. The seed.sql INSERTs in commit
-- 917d044 already include ON CONFLICT DO NOTHING — they just had no
-- target before this constraint existed.
BEGIN;
-- 1. Dedupe — keep the lexicographically-smallest id per natural-key
-- bucket. Picks deterministically; doesn't depend on insertion order.
DELETE FROM transactions a
USING transactions b
WHERE a.canonical_asset_id = b.canonical_asset_id
AND a.source_id = b.source_id
AND a.transacted_at = b.transacted_at
AND COALESCE(a.gross_transaction_price, -1) = COALESCE(b.gross_transaction_price, -1)
AND a.id > b.id;
-- 2. Enforce going forward.
ALTER TABLE transactions
DROP CONSTRAINT IF EXISTS transactions_natural_key;
ALTER TABLE transactions
ADD CONSTRAINT transactions_natural_key
UNIQUE (canonical_asset_id, source_id, transacted_at, gross_transaction_price);
-- 3. Bookkeeping
INSERT INTO schema_migrations(filename) VALUES ('0002_transactions_unique.sql')
ON CONFLICT (filename) DO NOTHING;
COMMIT;