Case Study

Appointment Booking and Calendar Integration

An appointment platform that rechecks availability, manages temporary slot holds and preserves accepted bookings when integrations fail.

This appointment scheduling software case study follows a booking platform. Each host defines their event types and accepts bookings, then handles any reschedule or cancellation that comes later. Calendars, video meetings and payment services all connect to that flow. The appointment itself lives in one booking record.

That booking record matters, because choosing a free slot is only the start. The platform must also weigh the host's working hours, the calendar conflicts and other visitors reaching for the same time.

The challenge

Two visitors can choose a slot before either one finishes the form. A calendar can also change while a visitor is still deciding. The server therefore cannot accept an appointment just because the page showed that time as free a few minutes earlier.

A second problem shows up after acceptance. The video or calendar provider may not respond. We needed to keep the appointment, log the failed integration and leave the missing link ready for follow-up.

What we built

Hosts set the event duration and buffers. They also set advance notice, booking windows and limits for each event type. Weekly schedules and date overrides define the hours. Holidays and out-of-office settings mark the time a host is away. Custom questions gather what a visitor must provide before they can submit the booking form.

The availability service works out bookable times from those settings. It removes busy calendar periods and existing appointments. It then applies the event limits and leaves out slots that other visitors are holding. Hosts can open a troubleshooting view to see how the availability was worked out.

Selecting a slot creates a hold with an expiry. The visitor fills in the form without holding a database transaction open, so an abandoned hold frees up again once its deadline passes. An accepted booking moves through confirmation and on to rescheduling or cancellation, and it also carries internal notes and a no-show status.

For paid appointments, the payment confirmation updates that same booking record. Emails, audit records and notifications to connected systems follow the booking through its life.

Validate availability at submission

The server runs the full set of availability checks again when a visitor submits the booking. Those checks cover the permitted times, the duration and the booking limits, and they also look for blocked email addresses. Bot checks and rate limits run next to them.

A database uniqueness rule gives a final guard for the same host and time interval. A Prisma extension turns the start, end and host into a UUIDv5 idempotency key, so two repeated submissions cannot both become accepted records. The availability checks still run next to this database constraint. Cancelling or rejecting a booking clears the key, which opens that interval again.

Preserve the appointment across integration failures

The integration sequence creates the video meeting before the calendar entry, so the meeting link can appear in the invitation. Calendar and other connected-system updates come after that.

When those integrations fail, the application logs the problem and keeps the booking. The missing external entry can be sorted out later, without losing the appointment. Calendar, video and payment connectors share one integration structure, and signed webhooks carry booking events to other applications.

Make operational work explicit

A dry-run path runs the booking logic without saving appointments or sending email, so the team can check an event type before it goes live. Audit records keep the actor behind a booking change, even after that account is deleted.

Background work needs a configured scheduler to drain the stored tasks, since saving a task does not run it on its own. Deployment therefore brings both the scheduler and the chosen task provider.

Project success

Hosts can publish times that follow their schedules, their event rules and their connected calendars. When a visitor submits, the server rechecks availability. It uses a unique key to guard against accepting the same host and interval twice.

An accepted appointment survives a failed calendar or video update. The host can repair the missing external entry from the booking that was kept, and audit records show what changed later. Dry runs give a way to check how an event behaves before bookings open to visitors.

Technology stack

Application

TypeScript, Next.js, React

Application API

tRPC

Integration API

NestJS

Data access

Prisma, Kysely, PostgreSQL

Build tooling

Turborepo

Task execution

Database-backed tasks, external task service or synchronous execution

Recognize the pattern?

If one of these looks like your situation, the discovery call is where we find out how close.