Demo environment. Clinics, staff and shifts are fictional, and the demo resets nightly.

Rota

Shifts that don't collide.

Multi-tenant scheduling with the boring parts done properly: SSO, passkeys, billing, audit.

Try the demo with a shared persona

Harbourside Clinics is fictional: three locations, twenty people, four weeks of shifts. Demo sign-ins are shared, last two hours and reset nightly. Prefer your own data? Create an account.

A drop that would double-book someone snaps back, and the reason appears under the cell.

What's inside

Separate by design
One clinic group's rota is invisible to every other. The boundary is enforced in the types, the query helpers, the linter and the database's foreign keys, and a test suite tries to break each layer.
Sign-in that holds up
Argon2id passwords, passkeys, authenticator-app codes with recovery codes, and Google and Microsoft sign-in where they are configured. Every active session is listed and can be revoked.
Four roles
Owners, admins, schedulers and staff. Staff can claim open shifts and ask to swap their own; only owners reach billing. The same policy decides what each page shows and what each query allows.
No double-booking
Overlapping shifts for one person are refused by the database itself, not just by the interface, so a second tab, an import or an API call cannot sneak one in.
A record of every change
Who did what, to which shift, with the values before and after. The table is append-only: the database rejects edits and deletes, and secrets are redacted before anything is written.
Mail without a mail server
Verification, reset and invitation mail go to a sandbox outbox until a Resend key is added. Nothing in this demo is ever sent to a real inbox.