Files
accounted/supabase/migrations/20240101000042_prevent_overlapping_fiscal_periods.sql
T
Jakob WennbergandClaude Opus 4.6 6956a757f3 feat: consolidate booking templates from 100 to 48 and improve codebase
Reduce booking template library to eliminate duplicate suggestions when
users describe transactions. Templates with identical accounting treatment
(same account + VAT) are merged, keywords consolidated, and the entire
subscriptions group is eliminated. Also includes prior work on reports,
extensions, and transaction improvements.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 10:21:10 +01:00

70 lines
2.4 KiB
SQL

-- Prevent overlapping fiscal periods per user.
--
-- Root cause: the UNIQUE(user_id, period_start, period_end) constraint only
-- blocked exact-duplicate date pairs, not overlapping ranges. Multiple code
-- paths (onboarding re-runs, SIE import, manual API) could create periods
-- with different but overlapping dates for the same user.
--
-- Fix: enable btree_gist, consolidate existing overlaps, add an EXCLUDE
-- constraint using daterange overlap (&&).
-- 1. Enable btree_gist for exclusion constraint support (uuid + daterange)
CREATE EXTENSION IF NOT EXISTS btree_gist;
-- 2. Temporarily disable immutability triggers to allow fiscal period
-- consolidation. This is a structural data fix (moving entries between
-- periods), not an accounting modification.
ALTER TABLE public.journal_entries DISABLE TRIGGER enforce_journal_entry_immutability;
-- 3. Consolidate overlapping fiscal periods: for each pair belonging to the
-- same user, move all references from the older period to the newer one,
-- then delete the older period.
DO $$
DECLARE
overlap RECORD;
BEGIN
FOR overlap IN
SELECT DISTINCT ON (a.id)
a.id AS old_id,
b.id AS new_id
FROM public.fiscal_periods a
JOIN public.fiscal_periods b
ON a.user_id = b.user_id
AND a.id != b.id
AND a.period_start <= b.period_end
AND a.period_end >= b.period_start
AND a.created_at < b.created_at
ORDER BY a.id
LOOP
UPDATE public.journal_entries
SET fiscal_period_id = overlap.new_id
WHERE fiscal_period_id = overlap.old_id;
UPDATE public.sie_imports
SET fiscal_period_id = overlap.new_id
WHERE fiscal_period_id = overlap.old_id;
UPDATE public.voucher_sequences
SET fiscal_period_id = overlap.new_id
WHERE fiscal_period_id = overlap.old_id;
UPDATE public.fiscal_periods
SET previous_period_id = overlap.new_id
WHERE previous_period_id = overlap.old_id;
DELETE FROM public.fiscal_periods WHERE id = overlap.old_id;
END LOOP;
END $$;
-- 4. Re-enable the immutability trigger
ALTER TABLE public.journal_entries ENABLE TRIGGER enforce_journal_entry_immutability;
-- 5. Add exclusion constraint: no two fiscal periods for the same user
-- may have overlapping date ranges.
ALTER TABLE public.fiscal_periods
ADD CONSTRAINT no_overlapping_fiscal_periods
EXCLUDE USING gist (
user_id WITH =,
daterange(period_start, period_end, '[]') WITH &&
);