DEV Community

Ahmed Farouk
Ahmed Farouk

Posted on AI-assisted

How I stop double bookings in a booking app: let Postgres refuse them

Every salon, barber and clinic wants a booking app, and every booking app has the same hard part: availability and double-booking. I built a kit around that problem, and this is the design decision that mattered most.

Let the database refuse double bookings

The tempting way is to check "is this slot free?" in the app, then write the booking. Two people tapping the same slot at the same moment can both pass that check.

So the rule lives in Postgres, in two places:

  1. Availability is a database function. The app never computes free slots. It calls get_available_times and shows what comes back.
  2. Overlaps are impossible by constraint. The bookings table has an exclusion constraint (using the btree_gist extension) so two active bookings for the same staff member cannot overlap in time. If a race slips past everything else, the database rejects the second insert and the app shows a clear "that time was just taken" message.

The app only ever calls functions such as create_booking. It does not write to the bookings table directly.

Row-level security on every table

Every table has row-level security with explicit policies, and the functions the app can call check who is asking before they do anything. Internal functions are not callable by signed-in users at all. This is the part I would check first in any Supabase project you buy or inherit.

Time zones and right-to-left

Times are stored in UTC and shown in the business's own time zone, with the zone labelled, so a client travelling abroad still sees the salon's local time. The interface is in English, Arabic (right-to-left) and Spanish. Styles use start/end rather than left/right, so the layout mirrors correctly.

What it is

Slotsmith is a source-code kit: a customer app, a staff mode and an owner dashboard in one TypeScript codebase (Expo / React Native, for iOS, Android and web), a Supabase backend, and Stripe Checkout for payments.

The full kit is a paid download and I am the author. I built it with AI coding assistance (Claude Code), and the demo photos are AI-generated.

Limitations

Payments use Stripe Checkout rather than a native in-app purchase flow. You bring your own Supabase project and Stripe account. Push notifications and social sign-in need a development build rather than Expo Go.

If you build booking apps for local businesses, I would like to hear what is missing.

Top comments (0)