
Operating-room time is a clinic's scarcest resource, yet most of it is scheduled through shared spreadsheets and phone calls. Overlapping bookings slip through, nobody has a live view of the day, and every change triggers another round of manual coordination — the kind of friction that quietly compounds as a clinic grows.
Kliniq is a from-scratch scheduling platform — a Kotlin / Spring Boot 3 backend with jOOQ over PostgreSQL and a SvelteKit frontend. Overlapping bookings aren't merely validated away in application code; a Postgres EXCLUDE constraint makes them impossible to insert at all. Server-Sent Events keep every open schedule live, drag-and-drop reschedules a booking in place, and a self-hosted auth stack (Argon2id + WebAuthn passkeys) runs the whole thing with no third-party identity provider. Built and shipped solo, end to end — and running: the demo at kliniq.izotov.dev is this codebase with a seeded clinic.
Double-Bookings Possible
Postgres EXCLUDE constraint
RBAC Roles
Admin · Manager · Staff
Real-Time Schedule
Server-Sent Events push
Backend tests
plus 8 Playwright e2e

A Postgres EXCLUDE USING gist constraint over each operating room and a tstzrange makes two overlapping bookings physically impossible to insert — integrity guaranteed by the database, not by hopeful application-level checks.
Every booking moves through a deterministic lifecycle — Scheduled → In-Progress → Completed / Cancelled — with guarded transitions in the domain layer that reject illegal jumps before they reach the database.
Server-Sent Events stream every create, edit and cancel to all connected dashboards, so the schedule stays live across the clinic with no polling and no manual refresh.
Argon2id hashing, WebAuthn passkeys, Redis-backed sessions, CSRF protection and per-IP rate limiting — a complete identity stack built from scratch, with no Auth0 or external provider.
Live Demo
The demo runs at kliniq.izotov.dev with three operating rooms and a fortnight of bookings. Sign in as any demo surgeon — [email protected], password DemoSurgeon2026! — and move a booking; a second browser tab sees the change without a refresh.

Happy to explain why the double-booking guard lives in the database rather than the interface, and what that cost in complexity elsewhere.