{
  "id": 15388827,
  "title": "The Double-Booking This Schema Is Built to Allow",
  "url": "https://urgent.news/2026/10/18/the-double-booking-this-schema-is-built-to-allow",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-18T10:01:06.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/iurii_rogulia/the-double-booking-this-schema-is-built-to-allow-4big"
  },
  "original_language": "en",
  "account": "When planning appointments for beauty professionals using a PostgreSQL database, it is crucial to prevent double bookings. The most common solution is to use an EXCLUDE constraint with btree_gist, specifying && on a tstzrange. This approach is effective at the database level, eliminating the need for additional application code. However, the booking SaaS KRI designed for beauty businesses requires a different rule. The business needs to ensure that a client's booking does not overlap any live booking for that specialist, whether it originated from a client or the owner. This order-dependent rule cannot be satisfied by a simple UNIQUE or EXCLUDE constraint over the booking intervals. Instead, KRI implements the client-facing guard within an application transaction. A database routine or trigger with appropriate locking could also be an alternative design, but using the application path consistently is essential.",
  "summary": "Ask anyone who knows PostgreSQL how to stop two clients booking the same specialist at the same time, and the answer comes fast: an EXCLUDE constraint with btree_gist , one && on a tstzrange , done at the database level, no application code to trust. It’s the right answer to the question most people are asking. It’s the wrong answer to the one KRI , the booking SaaS I designed and built for…",
  "key_points": [
    "KRI SaaS requires order-dependent booking rule",
    "Simple UNIQUE or EXCLUDE constraints insufficient",
    "Application transaction implements client-facing guard"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}