diff --git a/backoffice/db/init.sql b/backoffice/db/init.sql index 8579953..a1c8476 100644 --- a/backoffice/db/init.sql +++ b/backoffice/db/init.sql @@ -166,16 +166,23 @@ ALTER TABLE bookings ADD COLUMN IF NOT EXISTS resource_id text; ALTER TABLE bookings ADD COLUMN IF NOT EXISTS during tstzrange GENERATED ALWAYS AS (tstzrange(start_time, end_time, '[)')) STORED; --- ALTER TABLE ... ADD CONSTRAINT has no IF NOT EXISTS form, so guard by name --- to keep this file safe to re-run on every deploy like everything above it. +-- ALTER TABLE ... ADD CONSTRAINT has no IF NOT EXISTS form, so drop-then-add +-- unconditionally to keep this file safe to re-run on every deploy like +-- everything above it. The WHERE clause is load-bearing: without it, a +-- cancelled booking's old time range stays "occupied" forever, permanently +-- blocking that resource+slot from ever being booked again even though the +-- booking itself is dead -- found 2026-09-12 when a cancelled test booking +-- blocked a real reschedule into the same slot. DO $$ BEGIN - IF NOT EXISTS ( + IF EXISTS ( SELECT 1 FROM pg_constraint WHERE conname = 'bookings_no_overlap' ) THEN - ALTER TABLE bookings ADD CONSTRAINT bookings_no_overlap - EXCLUDE USING gist (resource_id WITH =, during WITH &&); + ALTER TABLE bookings DROP CONSTRAINT bookings_no_overlap; END IF; + ALTER TABLE bookings ADD CONSTRAINT bookings_no_overlap + EXCLUDE USING gist (resource_id WITH =, during WITH &&) + WHERE (status <> 'cancelled'); END $$; ALTER TABLE clients ADD COLUMN IF NOT EXISTS slug text UNIQUE;