fix(equipment): DB-enforced reservation no-overlap (D1, P0)
reserveEquipment was check-then-insert with no DB guard: two concurrent requests both passed the in-memory overlap check and double-booked a machine. Migration 042 adds btree_gist + a GiST EXCLUDE constraint (equipment_id =, tstzrange && ) WHERE status='reserved', making the DB the arbiter; the action maps the 23P01 violation to the existing friendly overlap message. App-side check kept as a fast pre-check. Schema + DB maps updated.
This commit is contained in:
@@ -20,6 +20,9 @@
|
||||
-- 1. EXTENSIONS
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
-- btree_gist: provides `uuid WITH =` for the equipment_reservations overlap
|
||||
-- exclusion constraint (see section below / scripts/042).
|
||||
CREATE EXTENSION IF NOT EXISTS btree_gist;
|
||||
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
@@ -2277,6 +2280,18 @@ CREATE INDEX IF NOT EXISTS idx_equipment_res_space ON public.equipment_reser
|
||||
CREATE INDEX IF NOT EXISTS idx_equipment_res_equipment ON public.equipment_reservations (equipment_id, starts_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_equipment_res_member ON public.equipment_reservations (member_id);
|
||||
|
||||
-- DB-enforced no-overlap (equivalent to scripts/042). Only 'reserved' rows
|
||||
-- conflict; the app-side check stays as a fast pre-check, the DB is the
|
||||
-- arbiter under concurrency. Idempotent: DROP then ADD.
|
||||
ALTER TABLE public.equipment_reservations
|
||||
DROP CONSTRAINT IF EXISTS equipment_reservations_no_overlap;
|
||||
ALTER TABLE public.equipment_reservations
|
||||
ADD CONSTRAINT equipment_reservations_no_overlap
|
||||
EXCLUDE USING gist (
|
||||
equipment_id WITH =,
|
||||
tstzrange(starts_at, ends_at, '[)') WITH &&
|
||||
) WHERE (status = 'reserved');
|
||||
|
||||
ALTER TABLE public.equipment ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE public.equipment_reservations ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user