HealthTech · Software clínico

FichaMedica

Historia clínica electrónica multi-tenant

Sistema multi-tenant de ficha clínica electrónica donde cada médico administra sus propios pacientes, consultas, recetas, análisis de laboratorio e imágenes médicas — con agenda semanal validada, signos vitales con flags clínicos automáticos y un portal de paciente con acceso read-only a su propia historia.

FichaMedica

El reto

Las historias clínicas electrónicas suelen vivir en plataformas pesadas de hospital que no encajan con la realidad de un consultorio individual: licencias caras, instalaciones complejas, datos del médico mezclados con los de otros usuarios y un portal de paciente que muchas veces ni siquiera existe.

FichaMedica nace como proyecto de I+D para responder a una pregunta concreta: ¿cómo se vería una ficha clínica electrónica diseñada multi-tenant desde el primer commit, donde cada médico administra sus pacientes en aislamiento estricto y el paciente tiene su propio portal sin acceso al panel del médico?

La solución

FichaMedica es un sistema multi-tenant row-level: toda tabla con dueño lleva doctor_id, el JWT carga el tenant del que escribe o lee, y cada query filtra obligatoriamente por ese tenant antes de devolver una fila. Sobre esa base modelamos 9 entidades del dominio clínico (doctores, pacientes, consultas, recetas, análisis, imágenes, signos vitales, citas, horarios) con relaciones cruzadas y eager-loading optimizado.

Lo que cubre la app

  • Dashboard rico — KPIs del consultorio (pacientes, consultas, recetas, análisis, imágenes), gráfico diario de consultas de 15 días dibujado en SVG inline (sin librerías de charts), distribución por edad/sexo, pacientes con flags clínicos, top diagnósticos, top exámenes, próximas citas y galería de imágenes recientes.
  • Agenda con calendario semanal — bloques de horario laboral por día con soporte de turnos partidos, validación dura de “dentro del horario” + check de overlap al crear o editar citas, bloques posicionados absolutamente sobre la grilla horaria.
  • Workflow Atender cita → consulta — un click cierra la cita y abre el form de consulta prellenado con motivo y fecha, enlazando ambos registros en una sola transacción y refetcheando el dashboard automáticamente.
  • Signos vitales con interpretación automática — IMC calculado al vuelo y 14 flags clínicos en español (fiebre, hipertensión, taquicardia, hipoxemia, obesidad I/II/III, dolor severo, etc.) basados en thresholds estándar.
  • Análisis de laboratorio con flags — cada resultado se compara contra rangos de referencia y se etiqueta normal / low / high / abnormal automáticamente; conteos por análisis y agregado en el dashboard.
  • Imágenes médicas con URLs presignadas — el navegador hace upload directo a MinIO vía PUT presignado (no pasa por el backend), GET presignado con TTL de 15 min para visualización, lightbox modal con visor en fondo oscuro.
  • Portal del paciente — namespace /portal con 6 endpoints read-only scoped al user_id del principal, UI propia con degradado cyan→sky→indigo y secciones para citas, consultas con vitales, recetas, análisis con flags e imágenes.

Decisiones técnicas que importan

  • Multi-tenancy estricto desde la base de datosdoctor_id obligatorio, validación de tenant en cada uno de los 50+ endpoints REST, sin filtración cross-tenant verificada manualmente.
  • OpenAPI auto-generado por FastAPI, paginación server-side en todos los listados grandes, validación de bordes con Pydantic.
  • Imágenes fuera de la BD: MinIO con URLs presignadas para upload y visualización; CORS configurado para preflight; el backend solo orquesta los presigned URLs sin nunca tocar el binario.
  • Charts hechos a mano (Tailwind + SVG inline) en vez de meter Recharts/Chart.js — bundle más liviano y control total del look.
  • Generación de data demo escalable: importer de Synthea (mapea 1.000 pacientes sintéticos CSV al schema), localización con nombres/emails/teléfonos hispánicos, traducción ES de diagnósticos SNOMED, descarga de imágenes médicas reales desde Wikimedia Commons API con fallback a picsum.
  • Despliegue 100% reproducible: docker compose up levanta Postgres + MinIO + backend con hot-reload + frontend con hot-reload + migraciones Alembic auto-aplicadas + seed idempotente.

Resultados

  • Demo end-to-end navegable con 26 pacientes, 945 consultas, 410 recetas, 2 análisis curados con flags, 7 imágenes médicas reales y agenda activa con citas linkeadas a consultas — todo accesible desde el dashboard, la ficha de paciente y el portal.
  • Workflow médico ↔ paciente cerrado: el doctor agenda → atiende → genera consulta + vitales + recetas + análisis + imágenes; el paciente loguea con sus credenciales y ve toda su historia en su portal sin acceso al panel del médico ni a datos de otros tenants.
  • 50+ endpoints REST con OpenAPI auto-generado, paginación server-side y validación de tenant en cada uno.

Por qué importa

FichaMedica es un caso de I+D propio que valida un patrón que llevamos a custom apps reales: multi-tenancy row-level desde el primer commit, separación clara de paneles por rol, almacenamiento de archivos vía URLs presignadas para no cargar al backend, y data demo realista que permite mostrar la plataforma con números creíbles desde el día uno. Lo que aprendimos acá lo aplicamos directo cuando un cliente del sector salud — o de cualquier vertical que necesite aislamiento de tenants estricto — nos pide un sistema parecido con su lógica específica.