El sistema operativo de un grupo médico de quince clínicas

Sustituir un montón de herramientas desconectadas por una sola plataforma: sitio público, reservas, historiales de pacientes, logística de laboratorio, inventario en varios almacenes, contabilidad fiscal, RR. HH. e informes de publicidad - detrás de un único admin, con aislamiento por clínica y por región para nueve roles de personal.

13 clínicas en una sola plataforma
9 roles de personal, cada uno con su vista
8 sistemas sustituidos por uno
0 caídas que puedan bloquear una reserva
MI PAPEL
La arquitectura y todo el código. Definí el modelo de datos, escribí el backend y el front end, construí el admin y llevo la infraestructura sobre la que se apoya.
STACK
Django 5.2, PostgreSQL, Redis, Celery, front end renderizado en servidor, Nginx sobre Ubuntu endurecido.
LO MÁS DIFÍCIL
No las funcionalidades. Hacer que quince sedes compartan un solo sistema sin que ninguna pueda ver los pacientes de otra.

La situación

Un grupo médico con quince clínicas funcionaba sobre ocho cosas que no sabían unas de otras: una web, un widget de reservas aparte, un Excel para el stock, un segundo Excel para el laboratorio, un programa de contabilidad, una aplicación de fichaje, un dashboard de publicidad y un buzón compartido. Cada cifra que importaba existía en al menos dos sitios, y donde no coincidían nadie podía decir cuál era la correcta.

Eso no es un problema de tecnología. Es un problema de negocio que aparece como un problema de tecnología, y es exactamente el tipo de trabajo que mejor se me da.

Lo que construí

Una sola plataforma Django, que sirve las quince sedes: la web pública, las citas, las fichas de los pacientes, el CRM, la logística de laboratorio, el stock de varios almacenes, la contabilidad fiscal, recursos humanos y los informes sobre el gasto en publicidad. Todo detrás de un único admin, con aislamiento a nivel de clínica y de región para nueve roles de personal, de modo que una recepcionista de una ciudad no puede ver los pacientes de otra ciudad y ni siquiera tiene que pensar por qué.

Las funcionalidades son la parte banal. Tres de los sistemas que hay debajo merecen que los describa, porque son la diferencia entre un software que funciona el día del lanzamiento y un software en el que sigues confiando dos años después.

Un flujo de consentimiento que resistiría en un juzgado

El consentimiento médico bajo el RGPD no es un checkbox con un timestamp. Lo que tienes que poder producir, más tarde, es exactamente el documento con el que una persona concreta estuvo de acuerdo en un momento concreto - no tu versión de ahora.

Así que el flujo genera el documento, lo muestra en pantalla, confirma la identidad con un código enviado por SMS y almacena el PDF renderizado junto con el texto, el idioma en el que se mostró, la dirección desde la que se firmó y una cadena de hashes que lo vincula a la ficha. Si modificas la plantilla después, cambia lo que ve el siguiente paciente y nada de lo que aceptaron los anteriores.

La regla de debajo: el consentimiento se da a una frase, no a un booleano. Si tu sistema almacena true, ha almacenado lo que no debía.

El stock como registro, no como número

La mayoría de los sistemas de stock mantienen una columna quantity en la que escribe el código. Esa columna acaba estando mal en algún momento - una condición de carrera, un reintento, un clic equivocado, una transferencia aplicada a medias - y una vez que está mal ya no tienes cómo averiguar por qué, porque la respuesta sobrescribió la prueba.

Aquí la cantidad no se almacena. Cada recepción, transferencia, consumo y corrección es una entrada inmutable con signo, y el saldo de cualquier almacén es la suma de las entradas que lo tocan. Las correcciones añaden el inverso en lugar de editar el historial. Eso convierte la conciliación en una propiedad del diseño, no en una tarea mensual, y significa que la respuesta a "¿por qué tenemos once de estos?" está siempre disponible y siempre completa.

Más abajo en la página encuentras una versión funcional de la idea.

Un calendario que no puede solapar dos citas

Las citas de quince clínicas se solapan constantemente, y la recepción necesita ver un día entero de una vez, sin que dos citas ocupen nunca el mismo hueco. Ese es el problema de interval scheduling: ordenas por hora de inicio y después pones cada cita en el primer carril cuya cita anterior ya ha terminado.

Lo que hace que merezca la pena implementarlo bien y no de forma aproximada es que la variante greedy es demostrablemente óptima - el número de carriles que produce es exactamente el mayor número de citas que se solapan en un mismo instante, es decir, un límite inferior duro que ningún algoritmo puede batir. Puedes ver cómo se cumple en la demo de más abajo.

La realidad rumana

La facturación, el libro de caja y los drivers para las impresoras fiscales que exige la ley. Trabajos protésicos rastreados por mensajería entre la clínica y el laboratorio. Fichaje con un pequeño cliente de escritorio que envía un heartbeat. Nada de todo esto es ingeniería interesante y todo junto es la diferencia entre un sistema que las clínicas usan y uno que esquivan.

La decisión que defendería con más fuerza

Cada dependencia externa de la plataforma hace fail open. Si el proveedor de SMS está caído, si la API de publicidad limita las peticiones o si el servicio de facturación da timeout, la cita se completa igualmente, y el trabajo que queda entra en una cola y se marca para una persona.

La alternativa - rechazar una cita porque un tercero no está disponible - significa externalizar tus ingresos al uptime de otro. Las protecciones internas van al revés: los rate limits, la validación y el honeypot hacen fail closed, porque ahí no tienes a quién echarle la culpa.

Lo que haría de otra manera

Construiría la capa de informes antes. Diseñé el registro y la planificación correctamente desde el principio y dejé que los informes se fueran acumulando solos, lo que significó que los primeros tres meses de preguntas de dirección se respondieron con consultas escritas a mano por mí. Correcto, pero lento, y debería haberlo visto venir.

PRUÉBALO · EL ALGORITMO DE CITAS

El empaquetador del calendario, funcionando aquí.

Esta es la rutina de interval scheduling descrita arriba, en tu navegador. Añade citas y seguirá usando el menor número posible de carriles sin colisiones.

Esto es una demo interactiva y necesita JavaScript activado.

PRUÉBALO · EL LIBRO DE INVENTARIO

Stock derivado de movimientos con signo.

El mismo diseño de libro, simplificado a tres ubicaciones. Aquí nada guarda una cantidad - registra un movimiento y mira cómo los totales se recalculan desde el log.

Esto es una demo interactiva y necesita JavaScript activado.