<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ahmed Farouk</title>
    <description>The latest articles on DEV Community by Ahmed Farouk (@ahmed_farouk_9cf00a49e7a5).</description>
    <link>https://dev.to/ahmed_farouk_9cf00a49e7a5</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4223929%2Fb028dd44-22e2-4758-bd17-863e5742e23d.jpg</url>
      <title>DEV Community: Ahmed Farouk</title>
      <link>https://dev.to/ahmed_farouk_9cf00a49e7a5</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ahmed_farouk_9cf00a49e7a5"/>
    <language>en</language>
    <item>
      <title>How I stop double bookings in a booking app: let Postgres refuse them</title>
      <dc:creator>Ahmed Farouk</dc:creator>
      <pubDate>Tue, 03 Nov 2026 09:41:26 +0000</pubDate>
      <link>https://dev.to/ahmed_farouk_9cf00a49e7a5/how-i-stop-double-bookings-in-a-booking-app-let-postgres-refuse-them-49kg</link>
      <guid>https://dev.to/ahmed_farouk_9cf00a49e7a5/how-i-stop-double-bookings-in-a-booking-app-let-postgres-refuse-them-49kg</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let the database refuse double bookings
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;So the rule lives in Postgres, in two places:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Availability is a database function.&lt;/strong&gt; The app never computes free slots. It calls &lt;code&gt;get_available_times&lt;/code&gt; and shows what comes back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overlaps are impossible by constraint.&lt;/strong&gt; The bookings table has an exclusion constraint (using the &lt;code&gt;btree_gist&lt;/code&gt; 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.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The app only ever calls functions such as &lt;code&gt;create_booking&lt;/code&gt;. It does not write to the bookings table directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Row-level security on every table
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time zones and right-to-left
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://faroukian64.gumroad.com/l/slotsmith" rel="noopener noreferrer"&gt;Slotsmith&lt;/a&gt; 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.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Try it in the browser, no sign-up:&lt;/strong&gt; &lt;a href="https://slotsmith-demo.pages.dev" rel="noopener noreferrer"&gt;https://slotsmith-demo.pages.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free Lite version&lt;/strong&gt; of the customer app to run yourself: &lt;a href="https://faroukian64.gumroad.com/l/slotsmith-lite" rel="noopener noreferrer"&gt;https://faroukian64.gumroad.com/l/slotsmith-lite&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;If you build booking apps for local businesses, I would like to hear what is missing.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>reactnative</category>
      <category>supabase</category>
      <category>expo</category>
    </item>
  </channel>
</rss>
