
ZB Group Sdn Bhd runs three wedding halls, Elham, Juwita, and Asmara, and I am building their self-service booking system. The design goal is blunt: double-booking should not be prevented by careful code, it should be impossible, because the database itself refuses it.
Both sides of one business
ZB Group's halls are catered by Kak Mell Resources, my family's business, so I already build the software that runs the kitchen side of these events. This system covers the other side: the halls themselves. Same real-world relationship, software on both ends, and I design and build all of it.
![[PLACEHOLDER: hall selection page showing the three halls, dev build]](https://dogygijscxbcukykkurh.supabase.co/storage/v1/object/public/media/placeholders/image-coming-soon.png)
A booking is a state machine
Every booking moves through a state machine that runs inside database transactions. Picking a slot creates a 24 hour hold that releases itself if the customer walks away. Payment happens in milestones, an RM1,000 deposit, then 25%, 50%, and full. Rescheduling is a workflow, not an edit: at most three changes, three months notice, and admin approval on each one. Money is numeric(10,2), never a float, and timestamps are stored in UTC and rendered in Asia/Kuala_Lumpur. The build itself is spec-driven, one commit per phase with tests for each phase.
![[PLACEHOLDER: date and slot picker in the booking flow, dev build]](https://dogygijscxbcukykkurh.supabase.co/storage/v1/object/public/media/placeholders/image-coming-soon.png)
The database says no
The hard part was making double-booking impossible rather than unlikely. App-level checks always race: two customers can pass the same availability check in the same moment. So the guarantee lives in Postgres, in two layers. A partial unique index allows only one active booking per hall, date, and slot, and an advisory-lock transaction pattern serialises the attempts. A dedicated vitest suite proves it by firing ten parallel attempts at the same slot against a real Postgres: exactly one comes back held, the other nine get a clean SLOT_TAKEN error.
![[PLACEHOLDER: terminal output of the anti-double-booking test suite passing]](https://dogygijscxbcukykkurh.supabase.co/storage/v1/object/public/media/placeholders/image-coming-soon.png)
Where it stands
In development for ZB Group.