Praxis

A multi-tenant scheduling and clinical platform for professional practices, with a dental specialization: per-tooth clinical records on an FDI odontogram. Tenant isolation is not a feature of the application code. It lives in the database itself.

Role
Zenith product. The data model, the RLS design and the clinical extension are mine.
Stack
Next.js · Supabase (Postgres RLS) · TypeScript
Status
Designed, with a working multi-tenant schema. No live client yet, and this page says so.

Small professional practices run their agenda in one tool and their clinical records in another, or in none. A platform meant to serve many practices from shared infrastructure has a harder problem underneath: one clinic's data must be provably unreachable from another's, and each vertical (dental, aesthetics, veterinary) needs its own clinical layer without forking the product.

Multi-tenant from the schema up. Every table is scoped by tenant, and isolation is enforced by Postgres Row Level Security policies keyed to the current tenant, not by application code. The difference matters: application code can forget a WHERE clause on any query it writes. RLS cannot be bypassed by a missing filter, because the database refuses to return another tenant's rows at all.

  • Core scheduling schema shared by every vertical: clients, professionals, services, availability rules and exceptions, appointments, waitlist, client notes.
  • Vertical extensions activate per tenant type. The same platform, a different clinical layer, no fork.

The first vertical is dental, and it goes past scheduling into real clinical record-keeping: a dental profile per patient, an odontogram with marks per tooth in FDI notation, clinical notes, and procedures linked to the appointment they happened in. A dentist opens a patient and sees the mouth, not a spreadsheet.

screenshots coming soon
Isolation
Postgres Row Level Security keyed to the tenant, enforced by the database itself, not by application code.
Core schema
Clients, professionals, services, availability rules and exceptions, appointments, waitlist, client notes.
Dental extension
Dental profile per patient, FDI odontogram with per-tooth marks, clinical notes timeline, procedures linked to their visit.
Activation
Extensions switch on per tenant type. One platform, a different clinical layer, no fork.
Status
Working multi-tenant schema plus a complete interface mockup. No live client yet.

Praxis is at the stage every honest portfolio should label clearly: the schema works, the design is done, and the next milestone is a first pilot practice. What it already proves is the data-model discipline: isolation at the database layer and a clinical vertical built as an extension, not a fork.

RLStenant isolation enforced by the database, not by application code
32teeth tracked per patient on the FDI odontogram, mark by mark
1shared schema serving every vertical through per-tenant extensions