Fix: exclude cancelled bookings from the no-overlap constraint
Test backoffice (smb-crm) / test (push) Successful in 1m31s
Test backoffice (smb-crm) / test (push) Successful in 1m31s
bookings_no_overlap (the GiST exclusion constraint preventing
double-booking) had no WHERE clause, so a cancelled booking's old time
range stayed "occupied" forever -- permanently blocking that
resource+slot from ever being booked again, even though the booking
itself is dead. Found live: a cancelled test booking blocked a real
reschedule attempt into the same slot ("overlaps with an existing
appointment" even though nothing active was there).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+12
-5
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user