Files
myeasycms-v2/apps/web/supabase/migrations/20260417000004_courses_events_bookings_constraints.sql
T. Zehetbauer 5c5aaabae5
Some checks failed
Workflow / ʦ TypeScript (pull_request) Failing after 5m57s
Workflow / ⚫️ Test (pull_request) Has been skipped
refactor: remove obsolete member management API module
2026-04-03 14:08:31 +02:00

144 lines
3.9 KiB
SQL

-- =====================================================
-- Data Integrity Constraints for Courses, Events, Bookings
--
-- Adds CHECK constraints and partial unique indexes to
-- enforce business rules at the database level.
--
-- All constraint additions are idempotent — wrapped in
-- DO blocks that check pg_constraint before adding.
-- =====================================================
-- -------------------------------------------------------
-- COURSES
-- -------------------------------------------------------
-- reduced_fee must not exceed fee
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'chk_courses_reduced_fee_lte_fee'
) THEN
ALTER TABLE public.courses
ADD CONSTRAINT chk_courses_reduced_fee_lte_fee
CHECK (reduced_fee IS NULL OR reduced_fee <= fee);
END IF;
END;
$$;
-- min_participants must not exceed capacity
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'chk_courses_min_lte_capacity'
) THEN
ALTER TABLE public.courses
ADD CONSTRAINT chk_courses_min_lte_capacity
CHECK (min_participants IS NULL OR min_participants <= capacity);
END IF;
END;
$$;
-- end_date must be on or after start_date
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'chk_courses_date_range'
) THEN
ALTER TABLE public.courses
ADD CONSTRAINT chk_courses_date_range
CHECK (end_date IS NULL OR start_date IS NULL OR end_date >= start_date);
END IF;
END;
$$;
-- registration_deadline must be on or before start_date
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'chk_courses_deadline_before_start'
) THEN
ALTER TABLE public.courses
ADD CONSTRAINT chk_courses_deadline_before_start
CHECK (registration_deadline IS NULL OR start_date IS NULL OR registration_deadline <= start_date);
END IF;
END;
$$;
-- Unique course_number per account (partial index — allows NULLs and empty strings)
CREATE UNIQUE INDEX IF NOT EXISTS uix_courses_number_per_account
ON public.courses(account_id, course_number)
WHERE course_number IS NOT NULL AND course_number != '';
-- -------------------------------------------------------
-- EVENTS
-- -------------------------------------------------------
-- min_age must not exceed max_age
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'chk_events_age_range'
) THEN
ALTER TABLE public.events
ADD CONSTRAINT chk_events_age_range
CHECK (min_age IS NULL OR max_age IS NULL OR min_age <= max_age);
END IF;
END;
$$;
-- end_date must be on or after event_date
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'chk_events_date_range'
) THEN
ALTER TABLE public.events
ADD CONSTRAINT chk_events_date_range
CHECK (end_date IS NULL OR end_date >= event_date);
END IF;
END;
$$;
-- registration_deadline must be on or before event_date
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'chk_events_deadline_before_event'
) THEN
ALTER TABLE public.events
ADD CONSTRAINT chk_events_deadline_before_event
CHECK (registration_deadline IS NULL OR registration_deadline <= event_date);
END IF;
END;
$$;
-- -------------------------------------------------------
-- BOOKINGS
-- -------------------------------------------------------
-- At least 1 adult required
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'chk_bookings_min_adults'
) THEN
ALTER TABLE public.bookings
ADD CONSTRAINT chk_bookings_min_adults
CHECK (adults >= 1);
END IF;
END;
$$;
-- total_price must be non-negative
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'chk_bookings_price_non_negative'
) THEN
ALTER TABLE public.bookings
ADD CONSTRAINT chk_bookings_price_non_negative
CHECK (total_price >= 0);
END IF;
END;
$$;