Should I vibe code
Scheduling links with calendars, payments, and automated reminders
Two people load the same 3pm and both hit Book. Everything after that is a phone call you have to make.
?
Their verdict, the price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-04.
?
Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.
The honest answer
why the verdict is what it is
This is the commodity end of scheduling — booking links, availability rules, calendar sync, embeds — and the commodity is exactly why it is worth being precise about what an evening's work leaves out. The bug that defines this category is not glamorous: checking whether a slot is free is a read, writing the booking is a write, and the code an agent generates puts nothing between them. It works flawlessly while one person at a time uses your link, and it fails the first time your link is in a newsletter. Everything downstream of that — the confirmation that went to two people, the reschedule token a stranger can guess — is a phone call rather than a patch.
What actually breaks
not "if". the specific failures.
- The read-then-write race: availability is fetched, the human hesitates, someone else books, and your insert happily succeeds anyway
- The confirmation email, which is the moment the double booking becomes two people's plans rather than two rows
- Cancel and reschedule links, which are unauthenticated by necessity — if the token is short or sequential, a stranger can move somebody else's meeting
- Calendar sync drift, because a busy block created outside your app is invisible until you re-read free/busy on every request rather than on a schedule
- The OAuth refresh token, which is a permanent write key to a primary calendar sitting in an environment variable
- Availability rules the moment they meet reality: a lunch break, a two-week holiday, a minimum notice period and a maximum horizon are four features, not one
- Timezone rendering across a DST boundary, where the slot you offered in March is an hour off in April for exactly one participant
Is that you?
the verdict is a default, not a law
- One person's calendar, one meeting type, and a link you send individually rather than publish
- The booking write is a single atomic operation with a uniqueness constraint on the slot
- Cancel and reschedule links carry long random tokens that expire when the meeting does
- You are happy to reply by hand on the day the sync breaks
- The link is on a landing page, in a signature, or in a newsletter going to more people than can be in a room
- It writes into a colleague's calendar as well as your own
- You are taking payment at booking — read the Book Like A Boss entry first, because that is a different verdict
- Reschedule tokens are database ids, incrementing integers, or anything you could type by accident
- Nobody would notice for a week if the calendar sync silently stopped returning busy blocks
If you build it anyway
the checklist, then the prompt that enforces it
- Make the slot the unique key. A database constraint on (calendar, start, end) is what actually prevents a double booking; an availability check before the insert is decoration, and the popular 3pm will prove it.
- Re-read free/busy at submission time, not only when rendering the page. Between page load and submit there is a human deciding, and that gap is where the conflicting event appears.
- Generate long random tokens for cancel and reschedule links, scope them to one booking, and expire them after the meeting. These URLs travel through inboxes, calendar invites and forwarded threads.
- Store the OAuth refresh token encrypted, request the narrowest calendar scope that works, and handle revocation as an expected state rather than a crash — people do disconnect Google accounts.
- Every timestamp in UTC with the booker's IANA zone stored beside it. Render per viewer, never store an offset, and test both daylight-saving weekends before publishing the link.
- Rate-limit booking creation per IP and require a confirmed email before an event is written to a real calendar, or the first bot to find the form will fill your week.
- Make the failure path visible: if writing to the calendar provider fails after you have recorded the booking, that has to page you, not retry quietly into a queue nobody reads.
I am building a booking-link page that writes into a real calendar. Apply these
constraints in this order and refuse the shortcuts.
1. Start with concurrency, not the UI. The slot must be protected by a database
uniqueness constraint, and creating a booking must be one atomic operation.
Write the failing test first: two simultaneous requests for the same slot,
exactly one succeeds, the other gets a clean 'taken' response.
2. Re-check the calendar's free/busy at submit time as well as at render time,
and tell me plainly that checking availability and then inserting as two
separate statements is the defining bug of this category.
3. Cancel and reschedule links: long random tokens, one booking each, expiring
after the event. Never a row id, never sequential. Treat these URLs as public
because they end up in forwarded invites.
4. Encrypt the OAuth refresh token at rest, request the narrowest calendar scope
that works, and implement revoked-token and expired-token as normal states
with a visible reconnect path rather than as unhandled exceptions.
5. Store UTC plus the IANA timezone of each participant. No offsets, no local
times in the database. Add tests for both DST transitions.
6. Rate-limit booking creation per IP, and require an email confirmation click
before anything is written to a real calendar.
7. Only after all of the above, build availability rules — working hours,
breaks, minimum notice, maximum horizon, per-type durations. Implement them
as data, not as conditionals scattered through the query.
8. Make provider write failures loud. If the booking is recorded and the
calendar event is not created, that is an alert, not a retry into silence.
9. Log what changed on every booking with who and when, so a disputed 'I never
booked that' has an answer.
10. Refuse to add payment collection in this pass. If I ask, say that taking
money before the service turns this into refunds, disputes and idempotent
webhooks, and point me at that build as a separate project.
11. Out of scope: round-robin, team pooled availability, WhatsApp reminders.That one keeps you out of trouble. For the prompt that actually builds it, canivibecodeit.com has one.
their build prompt ↗Or don’t build it
the boring option, and the way back out
The moment the link goes somewhere public. A hosted booking product has already lost the argument with concurrency, daylight saving and revoked calendar tokens, and it has a free tier, so the comparison is not really about money — it is about whether you want to be the person emailing someone that their confirmed 3pm was given away.
Keep bookings in your own table with UTC timestamps, IANA zones and the provider event id for each one, so the calendar is a projection rather than the record. Keep the booking-link URL under a path you control and be prepared to 302 it, because scheduling links end up in email signatures and PDFs long after you have moved on. Disconnecting is easy in the other direction too: revoke the OAuth grant and the whole thing stops writing, which is the one genuinely reassuring property of this build.
Mature open-source scheduling platform; self-hostable, and the availability engine is worth reading before writing your own.
Smaller self-hosted scheduler with services, providers and durations already modelled; active development sits on the develop branch.
Questions
How likely is a double booking, really?
Rare at one visitor a day and near-certain the week your link is in a newsletter or on a pricing page. The pattern is not two people racing each other by milliseconds — it is one person loading the page, going to make tea, and submitting twelve minutes later against availability that was true when they arrived. Re-checking at submit time removes most of it; a uniqueness constraint on the slot removes the rest.
Why do the cancel links need random tokens? They only cancel a meeting.
Because they are unauthenticated by design — the invitee has no account — so the token is the only thing standing between a stranger and someone else's calendar. With sequential ids you can walk the whole booking table from a single confirmation email, see who is meeting whom and when, and move or cancel any of it. Long random tokens cost nothing and close that entirely.
Why is there no price on this page?
Because the pricing page renders entirely in the browser from Paddle price identifiers and publishes nothing in the HTML, so there was no figure to verify on 2026-08-04. House rule here is that an unverifiable price is left blank rather than copied from a third-party listing. There is a permanent free tier, which is the relevant comparison anyway.
Every week, someone ships something they shouldn’t have.
New verdicts, the worst thing that landed in the trap, and the occasional incident report. No other email, ever.
A booking link publishes your availability to the internet. Rate-limit it before you share it.
A poll link is a public roster of who's free when. That isn't a bug in Doodle — it's the design you're copying.
A booking link that takes a deposit is a shop. Refunds, no-shows and coupon codes are your accounting now.
last reviewed 2026-08-04 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice