shouldivibecodeit

Should I vibe codeAppointlet?

Scheduling pages with availability, forms, payments, and team routing

Timezone maths is the product, not a feature. It goes wrong twice a year, silently, in someone else's calendar.

?

Their verdict, the Premium price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-04.

Can you build it?asked by canivibecodeit.com ↗KINDAweekend project · weekend to multi-day
?

Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.

Should you ship it?asked by usYOUR FUNERALit’ll work. then it’ll get you.

The honest answer

why the verdict is what it is

The booking page is the easy half, and it is not the half you are paying for. What $12 a member buys is correctness in three places that all fail quietly: availability across DST boundaries and two calendar providers, the gap between showing a slot as free and actually writing the event, and a reminder that fires whether or not your cron host restarted. None of those announce themselves. A double-booked slot gets discovered by two people standing in the same doorway; a DST-shifted meeting gets discovered by one person waiting alone for an hour and quietly deciding you are unreliable. The Premium features sharpen it. Round-robin means you are scheduling colleagues who never read your code, and payment-at-booking means every scheduling bug arrives with a refund attached. Underneath all of it sits a Google refresh token that can read and write your entire calendar, living in a database you wrote over a weekend.

What actually breaks

not "if". the specific failures.

  • Availability across a DST boundary, where the slot renders at 3pm for the invitee and lands at 2pm in your calendar — once in March, once in October, and always to the people who booked furthest ahead
  • The double-booking race, because nothing in the generated implementation holds anything between "this slot is free" and "the event is written". Two tabs, one slot, two confirmation emails
  • The Google or Microsoft refresh token: a long-lived credential over your whole calendar, sitting in your app's database next to the sessions table
  • OAuth verification, because calendar scopes are restricted. An unverified app gets an interstitial warning screen and a hard user cap, and the review is a security questionnaire rather than a checkbox
  • The public page as an availability leak — anyone with the link reads exactly when you are free for the next two months without ever booking anything
  • Spam bookings, since an unauthenticated form that writes to a real calendar and emails a confirmation to an address the submitter typed is a week-filler and a small open mail relay in one request
  • Reminders, which fail closed and look like nothing: no email is indistinguishable from no problem until the no-show
  • Payment at booking, whose two failure modes are charged-with-no-slot and slot-with-no-charge, and both end in a refund and an apology
  • Round-robin, which is a fairness algorithm you now maintain, and which books the colleague whose holiday your availability rules never imported
  • Reschedules and cancellations made from the invitee's own calendar client, which never touch your app and leave your database confidently wrong
and then, at 3am

The complaint arrives as a one-line email from a customer who has been sitting in a video call for fifty minutes: "Are we still doing this?" You were not, because your calendar said 4pm and hers said 3pm. Finding it takes most of the morning — the slot generator built boundaries by adding seconds to a UTC timestamp, which is correct all year except across the last Sunday in October, so every booking made before the clocks changed for a meeting after them is off by an hour. There are nineteen. Eleven have already happened. Four were paid, which means four refunds and four separate explanations, and one of those was a first call with a prospect who does not reply to the apology. The code fix is twenty minutes. The list of people to email is the part that eats the day, because you have to work out, booking by booking, whose clock the confirmation was rendered in.

Is that you?

the verdict is a default, not a law

ship it if
  • It books only you, only inside one timezone, and a mistake costs a rescheduling message to someone who knows you
  • You are wrapping the calendar provider's own free/busy endpoint instead of computing free time from raw events yourself
  • There is no payment step and nobody else's calendar is involved
  • The page is unlisted, short-lived, and attached to one campaign you will switch off
don’t ship it if
  • Colleagues are being booked by it, because their no-shows are now your bug and their working hours are now your data model
  • Money changes hands at booking time and you have not decided, in writing, what happens when the charge succeeds and the event write fails
  • You derive availability yourself from stored events rather than asking the provider what is free
  • The booking page is public with no rate limit, no captcha and no email verification before a calendar event gets created
  • You cannot say where the OAuth refresh tokens live, whether they are encrypted at rest, and what revokes them

If you build it anyway

the checklist, then the prompt that enforces it

  1. Store instants in UTC and the invitee's IANA timezone name as separate fields, and never store a UTC offset. An offset is a fact about one moment; the zone name is the thing that survives a DST change.
  2. Ask the provider for free/busy rather than deriving it. Google's freeBusy and Microsoft's getSchedule already know about all-day events, declined invitations, recurrence exceptions and the user's other calendars. You do not.
  3. Make the booking write atomic: a unique constraint on host plus time range in the database, taken before any external call, with the calendar event as a retryable second step. Two people will click the same slot.
  4. Require a click on an emailed confirmation before anything reaches a real calendar, or your public page is a captcha-free way to fill someone's week.
  5. Keep OAuth refresh tokens encrypted with a key that is not in the repository, and build revoke-and-reconnect before you build connect. A token that has sat in a side project for a year is not a token you can assume is still private.
  6. If you take payment, use hosted checkout and reconcile from the webhook, not the browser redirect. Booking-confirmed and payment-captured are two states, and the honest design lets them disagree until the webhook resolves it.
  7. Send reminders from a durable queue with an idempotency key, and alert yourself when the queue is empty at a time it should not be — a silent reminder system looks exactly like a working one.
  8. Write the DST test first: a booking across spring-forward and autumn-back in two hemispheres, asserted in both parties' local wall-clock time. It takes an hour and it is the one test that would have caught the worst bug on this page.
the guardrail prompt
I am building a scheduling app: public booking pages, availability from a connected
Google or Microsoft calendar, intake forms, reminders and maybe payment. Assume
strangers will submit the form and that I will get the time maths wrong.

1. Fix the time model before any UI: UTC instants plus IANA timezone names for host
   and invitee, stored separately. Never store or compare UTC offsets.
2. Write the failing tests next — a booking across spring-forward and across
   autumn-back, in a northern and a southern zone, asserted in both parties' local
   wall-clock time. Put them in CI.
3. Get availability from the provider's free/busy API, never by iterating stored
   events; that misses all-day events, declines and recurrence exceptions.
4. Make the booking write atomic before it is pretty: a unique database constraint
   on host plus time range, taken before any external call. The calendar event and
   the confirmation email are retryable follow-ups.
5. The public page is unauthenticated. Rate-limit per IP and per email, add a
   captcha, and require a confirmation click before anything reaches a real
   calendar. Say plainly that without this it is a spam vector.
6. Store OAuth refresh tokens encrypted at rest with a key from the environment —
   never in the repo, never logged. Build revoke and reconnect alongside connect.
7. Only then reminders, from a durable queue with an idempotency key per booking
   per reminder, plus an alert when nothing has sent in a window where something
   should have.
8. If I add payment, use hosted checkout, reconcile from the webhook rather than
   the redirect, and let booking-confirmed and payment-captured disagree until the
   webhook lands.
9. Out of scope until I ask: round-robin, multiple hosts, white-labelling, video
   links. Round-robin means scheduling other people; I should decide that on its own.
10. Finish by listing every place the app can still double-book or shift a time,
    and remind me Appointlet is $12 a member.
paste this before you build — not after something breaks29 lines · 1998 chars

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

just pay for it

As soon as a second person's calendar is involved, or as soon as money is. $12 a member buys the two genuinely hard things: an availability engine that has already been wrong on every DST boundary on earth and been fixed, and somebody else's relationship with Google's OAuth verification team. Check the free tier first — five members and 25 meetings a month is more than most people building this actually have, which makes the real comparison $0 against your weekend.

$12/mo is cheaper than your weekend.

your exit plan, if you already built it

The migration is easy; the timing is not. Bookings are dated promises, so there is no clean cutover: export every future booking with its start instant, both timezone names, the invitee's email and the intake answers, recreate them in the commercial tool, then keep your old confirmation and cancellation URLs alive as redirects — those links are sitting inside strangers' calendar invitations and will be clicked for months. Revoke the calendar OAuth grants from the Google and Microsoft account pages when you are done, not just from your own database. And if you took payments, keep the ledger, because refunds get requested against bookings that no longer exist in any system you still run.

prior art · someone already did this
Cal.diy

The MIT-licensed community edition of Cal.com and the sane starting point, though its own README recommends personal, non-production use and the features it strips out are teams and workflows — precisely what Appointlet's paid tier sells.

Easy!Appointments

Long-running self-hosted PHP booking system with provider schedules, services and Google Calendar sync.

Questions

Is timezone handling really the hard part? I'm using a library.

The library handles conversion. It does not decide what your availability rules mean. "9 to 5, Monday to Friday" is a statement about wall-clock time in the host's zone, and a slot generator that produces it by adding fixed durations to a UTC instant is correct for about eleven months a year. The bug never shows up in testing, because you test in one zone in one week.

Why does taking payment at booking change the verdict?

It turns every scheduling bug into a money bug with a person attached. A double-booked free meeting is an embarrassing email. A double-booked paid meeting is a refund, a chargeback window, and someone who has already told a colleague you took their money for a slot that did not exist. Use hosted checkout, reconcile from the webhook, and keep booking-confirmed and payment-captured as distinct states.

My booking page is public but nobody knows the URL. Isn't that fine?

Two things happen to unlisted booking URLs: they end up in email signatures and get indexed, and they get scripted. An unauthenticated endpoint that writes an event to your real calendar and emails a confirmation to an address the submitter typed is a week-filler and a small open mail relay in the same request. Rate-limit it, and require a confirmation click before anything reaches a calendar.

What does the per-member pricing tell me about the build?

That the product is really about teams. Solo booking is a weekend. Pooled availability, round-robin with priorities and co-hosted meetings are a distributed fairness problem over other people's calendars, and the failure lands on a colleague who never chose your code. If you only need one calendar, build the simple thing and most of this page stops applying.

sources
  • GDPR Art. 5 — principles relating to processing of personal data
  • GDPR Art. 32 — security of processing
did you build it?

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.

also on the regret index
CalendlyDEMO ONLY

A booking link publishes your availability to the internet. Rate-limit it before you share it.

meetergoDEMO ONLY

A booking form is a personal-data intake endpoint that strangers fill in before you have ever spoken.

Acuity SchedulingYOUR FUNERAL

A booking form that asks “any conditions we should know about?” is a medical record with a submit button.

last reviewed 2026-08-04 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice