Healthcare · 2026 · Under NDA
A CRM for a medical clinic
Patients, doctor scheduling, electronic records and billing, in a system that never lets the data leave the clinic.

- Client
- A private medical clinic
- Year
- 2026
- Discipline
- CRM systems
- Timeline
- 1-2 months
The problem
Medical data is a special category under GDPR article 9, and it cannot be handled like an ordinary customer list. Off-the-shelf cloud CRMs almost always mean patient records sitting on somebody else's server in another country. At the same time the people using it are doctors and receptionists, not IT staff, so security cannot be paid for with a harder interface.
What we did
The system is self-hosted: it runs on the clinic's own network, with the database and files on the clinic's own server. The internet is needed only for patient reminders, and everything else keeps working without it. Personal data is encrypted, the admin account is behind a second factor, and every action on a record lands in an audit log. Permissions are not hard-coded: roles are configured per clinic. Inside are fifteen entities, including an ICD-10 catalogue and versioned medical records, with the interface in three languages.
The outcome
The system is delivered and being prepared for rollout, so it has no usage figures yet and we are not going to invent any. What can be checked today: the data never leaves the clinic, roles change without touching code, and every access to a patient record stays in the log.
Stack
- React
- TypeScript
- Vite
- Mantine
- Node.js
- Express
- MongoDB
- Docker
What the system does
Patients
- A record with insurance, allergies and chronic conditions
- National ID, phone, address and policy are stored encrypted
- Search across encrypted fields, through a blind index
- Duplicate control by national ID and by name with date of birth
- Anonymisation instead of deletion, as GDPR requires
- Consent to data processing, with a printable form
Appointments
- A day grid from 08:00 to 20:00, by doctor
- Moving an appointment by dragging it
- Overlapping times are rejected
- A doctor's weekly schedule and time off
- 7 states, from confirmed to no-show
- The calendar updates live in every open tab
- A waiting list for the slot that frees up
Medical records
- An encounter: complaints, examination, diagnosis, prescriptions
- An edit creates a new version, the old ones stay untouched
- Version history is visible in the interface
- An ICD-10 catalogue with autocomplete in three languages
- Examination templates, saved straight from the form
- A follow-up visit in one click
Files and printing
- Drag-and-drop upload, with the type checked against the file signature
- A forged extension is rejected
- Files live outside the webroot and are served only through the API
- Four PDF documents: summary, prescription, invoice, consent
- Every document prints in three languages
Billing
- Invoices numbered INV-YYYY-NNNN, with lines from the price list
- Amounts in whole minor units, no floating point
- Payment in cash, by card and through insurance
- Invoice status is recalculated from the amount paid
- A daily till report, by payment method
- An invoice created straight from a finished encounter
Security and access
- 17 atomic permissions, roles assembled in the admin panel
- Two-factor sign-in, mandatory for the administrator
- Escalating lockout after five failed attempts
- Permissions are re-read on every request, deactivation takes effect at once
- Audit log: sign-ins, record views, downloads
- Patient reminders over Telegram and email
Screens from the system

The clinic's day by doctor, with appointment states 
The patient record: encrypted data, insurance, GDPR consent 
The encounter journal with ICD-10 diagnoses 
Invoices and payments: cash, card, insurance 
Revenue, appointments, no-shows and new patients 
The role builder: 17 atomic permissions
In numbers
- data outside the clinicself-hosted, no cloud
- 0
- interface languagesEnglish, Romanian, Russian
- 3
- ICD-10 codes in the base catalogue
- 144