- Role
- Product, frontend and backend
- Years
- 2025–
- Stack
- React · TypeScript · Go · PostgreSQL · Redis · AWS
- Code
- Private
Clineo
Medical records software for clinics in Mexico. The goal is a doctor finishing an accurate, compliant clinical record during the consult, without the software getting in the way.


The problem
In Mexico, clinical records are regulated. NOM-004 says what a record must contain, that a signed note can no longer change, and that records are kept for at least five years. NOM-024 sets rules for the systems that store them: identity, access, traceability, security.
Most tools treat that as paperwork for later. Clineo puts it in the workflow: the doctor sees what the norm still requires while writing, and the rules that must never break are enforced by the system, not by good intentions.
What it does
Patients, an appointments calendar with public booking, structured clinical notes with templates, vital signs, consents, documents and files. Doctors, nurses and assistants each get the navigation and access their role needs. An admin panel covers compliance and the audit log.


Decisions
Compliance measured while writing
Each note shows a NOM-004 completeness score and the fields still missing, section by section. The same scoring rolls up per patient and per doctor for the compliance views.
A signed note is final
Every doctor has an Ed25519 key pair; the private seed is stored wrapped by KMS. Signing covers the SHA-256 of a canonical form of the note, done with a passkey, and a database trigger rejects any change to a signed note.
Encryption per patient
Personal and clinical fields are encrypted in the application with AES-256-GCM, using one data key per patient generated and wrapped by KMS. Cached keys never sit in Redis in the clear.
Rules enforced by the database
What must not change is protected with Postgres permissions: the audit log is append-only, clinical tables cannot be deleted from (only soft-deleted), and signing keys are write-once.
The admin never sees patients
Administrators have no patient access and the admin module cannot decrypt. Where it has to refer to a patient, it only gets an opaque slug.
An isolated public surface
Anonymous routes, like public booking, run as a separate binary. A test fails if it links clinical code, and its database role can only read specific columns and insert booking requests it cannot read back.
One instance per clinic
Each clinic gets its own database, cache, identity pool, encryption key and bucket. Nothing is shared, so there is no tenant column to get wrong.
AI only extracts
AI helps structure and summarize what the doctor wrote or dictated. It never diagnoses or adds information, and nothing generated enters the record without the doctor’s signature.
How it is built
The backend is a modular Go monolith: one process serves the authenticated API, with each module keeping its own router and boundaries, and the public surface runs apart. Every architectural choice is written down; there are 25 decision records so far.
Frontend and backend meet through written contracts: the frontend never invents an endpoint, and a script checks that every endpoint in a contract exists in the backend routes. Route snapshots, integration tests against a local AWS stack, and Playwright end-to-end tests cover each change.