All projects
Slate banner
SaaS / Booking & Scheduling · 2026 Live

Slate

Multi-tenant appointment booking admin SaaS for any chair, seat, or slot business.

Tech stack
Next.js 14 TypeScript Drizzle ORM PostgreSQL NextAuth Tailwind Recharts

The problem

Most appointment-booking tools are either rigid vertical apps (salons only, clinics only) or sprawling calendar suites that nobody on a small operations team enjoys driving. The operator's daily reality is mundane: see today, filter, edit, confirm, cancel, and stay out of double-booked situations. Slate focuses on that admin loop first and treats the customer-facing booking page as a downstream concern.

Goals

  • Host many independent businesses on one instance with strict per-tenant isolation
  • Give the operator a bookings list with server-side filters and inline status actions
  • Render a calendar week and day view with drag to reschedule
  • Block double-booking the same staff at the same time at the data layer
  • Surface analytics that an owner can read in under ten seconds

The solution

  • Next.js 14 app router with Drizzle ORM and Postgres, row-level isolation keyed by organization id
  • NextAuth session with org membership encoded so every query scopes to the active tenant
  • Bookings CRUD with server-side filters by date, status, staff, and customer search, plus optimistic inline edit
  • Calendar week and day views (staff columns) with drag-to-reschedule writing through to the same conflict rules
  • Conflict detection at the service layer so the API rejects overlaps regardless of which client created them
  • Analytics cards built on Recharts: daily count, 7-day outlook, top services, no-show rate, staff utilization
  • Mobile-responsive layout where the bookings table collapses to a card list under 640px

My role

  • Solo architect and engineer, requirements to deploy
  • Multi-tenant data model and the org-scoping pattern across every query
  • Bookings CRUD, per-staff availability rules, and the conflict-detection service
  • Calendar week and day views with the drag-to-reschedule write path
  • Analytics card pipeline and the mobile-responsive collapse pattern

UI direction

An operator-first admin surface in calm Tailwind with a single bookings list as the load-bearing screen, a calendar that earns its space, and analytics cards that read fast.

User flows

Operator runs the day

  1. 1 Operator signs in via NextAuth and lands on the analytics home
  2. 2 Clicks Bookings to see today's list, filtered by date and staff
  3. 3 Inline-confirms walk-ins, cancels a no-show, and edits a booking via the dialog
  4. 4 Switches to calendar week view to spot gaps and drags a booking to reschedule it
  5. 5 Conflict detection rejects an overlap before the write lands

Multi-tenant switch

  1. 1 Owner with access to multiple organizations opens the org switcher in the header
  2. 2 Picks a different tenant (e.g. Bella's Salon to Pinecrest Clinic)
  3. 3 The active session re-scopes; every list, calendar, and analytics card reloads against the new tenant
  4. 4 No data crosses tenants because every query is keyed on organization id

Screenshots

Click any image to open at full size.

Key learnings

  • Row-level tenant isolation enforced in the data layer (not just the UI) is the difference between a real multi-tenant SaaS and a single-tenant app with a dropdown
  • Conflict detection belongs in the service layer, not the UI, so the calendar drag handler and the bookings form both go through the same guard
  • An operator-first admin built before the customer booking page keeps the build honest; the screen the team lives in gets the design hours
  • Drag-to-reschedule feels native only when the optimistic UI commits, the server rejects on conflict, and the client snaps back cleanly with the reason inline
  • Seed data named for a real business (Bella's Salon, Pinecrest Clinic) makes the demo land harder than a generic Lorem schedule

Want something like Slate?

I'm open to senior contract work. Let's talk about what you're building.

Get in touch