Why a booking system is harder than it looks
Showing open slots and booking them sounds like a solved problem. Four problems that only show up when the system serves a real business: duplicate bookings nobody reports, time zones, invitations and overlap policies.
Showing open slots is the easy part. The hard part shows up with real customers: two people booking the same slot at the same time, time zones that shift the slots, the moment the customer receives the invitation and becomes the audience, and deciding whether a conflict blocks or just warns.
A booking system seems like one of those things that's already solved. You show the open slots, the customer picks one, it's booked. It's been done a thousand times.
Then you put it to work in a real business and the problems that weren't in the sketch show up. Here are four we ran into. None of them is visible until it happens to you, and three of the four don't produce any error message.
1. The error the screen was hiding
We found something uncomfortable while reviewing how slots were queried: the part of the system that showed availability and the part that saved the booking weren't looking at exactly the same data.
The result is the worst possible one. The screen correctly hid a slot that was taken, but if a booking came in through another path, it was created anyway, right on top. No error, no warning, nothing odd on screen.
That's why it was never reported. A system that crashes is annoying, but it tells you. A system that saves two bookings in the same slot tells you nothing: the receptionist finds out when two people are standing at the front desk at the same time, and by then she can't tell whether it was a software error or someone's.
The lesson is general and we've used it ever since: when a system reads and writes the same data through different paths, sooner or later the two paths stop agreeing. It's not enough for the screen to look right. The screen looked right.
2. Time zones are not a formatting problem
This is the one everyone underestimates, us included.
Intuition says a time zone is a matter of presentation: you store the time and show it shifted depending on who's looking. That's not how it works in a calendar, because in a calendar the time defines things: what day it is, whether the booking falls within business hours, whether it clashes with another.
A concrete case: if someone defines a work block from one time zone and the location is in another, that block can fall on a different calendar day for each of them. So querying the database for "the blocks for that day" simply doesn't work, because the block you care about is stored with the date next to it. You also have to look at the day before and the day after, and evaluate each rule by the actual instant it happens.
That gave us two rules we apply to anything with dates:
- The time the customer picks is not reliable data. The browser says what moment it thinks it is; the slot that gets booked is decided by the server. If you accept the date and time the browser sends, you import its time zone without knowing it.
- When you add a time zone field to existing data, "empty" has to keep meaning what it meant before. In our case, empty means "interpreted in the location's time zone." If we had treated it as "no data," the day the update shipped every block already loaded would have moved. Nobody would have connected it to the deploy.
3. When the customer receives the invitation, the audience changes
A request that sounds harmless: besides being booked, the customer should get the calendar invitation.
What that request changes isn't the sending. It changes who can read the event. Until then the appointment was an internal record: it had the title the team uses, the internal notes, the firm's name, the names of the other parties involved. All of that became something a third party opens on their phone.
Three things we discovered there, and all three are counterintuitive:
Omitting is not deleting. When you update an event that already exists in Google Calendar, the fields you don't send stay as they were. So it's not enough to stop sending the internal notes: you have to send them explicitly empty, or the guest opens the event and reads what was there before.
By default, guests can see each other. It comes that way out of the box and it isn't neutral: in a law firm that means one party sees the opposing party on the guest list. You have to turn it off on purpose.
Moving an event is not deleting it and creating it again. It looks equivalent and it isn't: the event disappears from the guest's calendar and they get a new invitation, as if it were a different appointment. There's a "move" operation that keeps the event and its guests, and that's the one to use.
The rule we settled on, and that we now apply to anything that goes outside: nothing reaches the third party unless you've declared it public on purpose. It's not enough for a field to "normally not be sensitive."
4. "Block or warn?" is not a technical question
When two things clash on the calendar, the system has to do something. And the right answer depends on the business, not the software.
A clinic wants it blocked: if the exam room is taken, it's taken, and there's no case where allowing it makes sense. A law firm, on the other hand, sometimes needs to book two things at the same time knowing perfectly well why, and a hard ban forces it to work outside the system — which is the worst way to lose a calendar.
So we didn't decide it. It's a setting with three possible answers: block, allow, or warn and let it through — which rejects the operation but offers the option to "book anyway," with the conflict in view.
The generalization holds for any automation: when a rule changes from business to business, it's configuration, not code. And if the system forces you to work outside it even once in a while, you no longer have a reliable calendar.
What we learned
- The worst errors are not the ones that fail loudly. A system that crashes tells you. One that saves things wrong doesn't.
- A time without a time zone is incomplete data, and the customer's browser is not the source of truth.
- When a third party gets to look, everything you didn't declare private is public.
- Rules that change from business to business are configured, not programmed.
None of the four is really a lesson about bookings. They're the same four that show up every time a process that was done by hand starts being done by a system.
Are you booking by hand?
If your business still coordinates appointments over WhatsApp, Excel or a notebook, we can look together at what getting it organized would take. The diagnosis is free and comes out of a short conversation.
We'll be in touch soon.
We solve this in Custom software and ERP →
