Healthcare · Multi-Tenant SaaS

Paper intake, replaced by a system that remembers.

Sirona Mind is a HIPAA-minded clinic management and patient wellbeing platform for mental health practices — patient records, a drag-and-drop form builder, four role-scoped portals, OTP-secured access and full audit trails, across an unlimited number of clinics from one deployment.

tenancy · clinic as rootscoped
Group Adminall clinics
CLINIC AAdmin · Clinicians
CLINIC BAdmin · Clinicians
Patient portalown records only

every mutation written to the audit log · actor, entity, action

~510

Commits over ~9 months of active development

~390

Modules — ~180 Python, ~210 TypeScript/React

16

Core data models across 4 domain apps

12

GitHub Actions workflows

The problem

Every new clinic multiplied the admin load.

Clinic groups ran on paper intake forms, shared spreadsheets and manual reminder emails. There was no reliable record of who accessed or changed what — which becomes a problem the moment a compliance review happens.

The solution

One multi-tenant platform where the clinic is the unit of isolation. Admins onboard a clinic, build their own forms and assign them; clinicians work their patient list; patients complete everything in their own portal. Passwordless login removes password-reset support load, and every mutation is audit-logged automatically.

Role hierarchy

Four portals, four sets of permissions.

Each role gets its own dashboard, and the hierarchy controls exactly what that user can see and do. Full dark mode across all four.

L1Group AdminOversees every clinic in the group, onboards new ones, and sets group-wide configuration.
L2Clinic AdminRuns a single clinic: staff, patients, branding, and the forms that clinic uses.
L3ClinicianWorks a patient list, assigns forms and reviews submissions for their own caseload.
L4PatientCompletes assigned forms in a secure portal of their own, with nothing else visible.

What the platform does.

Multi-tenant by design

The clinic is the root tenant. Every queryset is role-scoped, so data cannot leak across clinics.

Dynamic form builder

Forms, sections, typed fields, conditional content and document uploads. Adding a new intake form needs no developer.

Form assignment and tracking

Assign to an individual patient or a patient group, then monitor submission status from a live dashboard.

Patient records and tasks

Profiles, task lists and grouping, so bulk operations run against a group rather than one record at a time.

Passwordless OTP access

A six-digit code by email, JWT access and refresh tokens, lockout after three failed attempts, and a 15-minute inactivity auto-lock.

Immutable audit log

Every create, update and delete is recorded with actor, entity and action — written, never edited.

Consent tracking

SMS and email consent changes are their own events, each stamped with actor, timestamp and IP address.

Automated email

Reminders and notifications are queued and sent asynchronously, so nothing blocks a clinician mid-workflow.

Architecture

Thin views, thick services.

Feature-module frontend

Each features/<domain> owns its api, types, hooks and components, so a domain can be read and changed in one place.

One API layer

Every HTTP call goes through a single central ApiService with automatic token refresh and retry on 401 — auth handling exists once, not per call site.

Strict service layer

Views stay thin and all business logic lives in services.py, keeping the domain testable independently of HTTP. OpenAPI/Swagger docs are generated, with an MkDocs site alongside.

Frontend

  • Next.js 16 (App Router)
  • React 19
  • TypeScript
  • Tailwind CSS v4
  • Radix UI

Backend

  • Django 5.1
  • Django REST Framework
  • JWT (simplejwt) + email OTP

Data

  • PostgreSQL 16
  • Redis 7
  • Celery 5 (worker + beat)

Platform

  • AWS S3
  • AWS SES
  • Docker Compose
  • GitHub Actions CI/CD

Engineering practice

Security scanning on every change.

Five scan classes run in CI on every change, with results published to GitHub’s Security tab as SARIF rather than sitting in a log nobody opens.

TruffleHog

Secret detection

Bandit

SAST — Django

Trivy

SAST — Next.js

DAST

Running environments

SBOM

Dependency inventory

Multi-environment pipeline

Separate QA, staging and production deploys, with a promote-to-staging flow and a dedicated hotfix path for changes that cannot wait for the queue.

QAStagingProductionHotfix path

Tests and quality gates

  • 54Backend pytest modules
  • 19Playwright end-to-end specs
  • 4Role portals covered with authenticated fixtures

Ruff, ESLint and Prettier run pre-commit, and builds are type-checked, so style and type failures never reach review.

What changed for the group.

  • Onboarding a new clinic is a configuration task, not a deployment.
  • New intake forms ship without engineering involvement.
  • Compliance questions are answered from the audit log rather than reconstructed from memory.

Regulated software, built to be reviewed.

Tenant isolation enforced in the queryset, an audit trail written on every mutation, and five classes of security scanning in CI — the things an auditor asks for, built in from the start.