Skip to content

code-sherpas/clinical-analysis-kata

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🧪 "Clinical Analysis Kata — Building the Patient Picture"

Pair programming kata para el proceso de selección de Buchinger.


Sobre los criterios de evaluación

Nos interesa observar:

  • cómo estructuras la información
  • cómo combinas datos de distintas fuentes
  • cómo decides qué forma parte del análisis
  • cómo manejas inconsistencias
  • cómo evoluciona tu diseño
  • cómo explicas decisiones

Importante

  • No necesitas terminar todo
  • Puedes simplificar lo que consideres
  • Puedes refactorizar en cualquier momento
  • Puedes hacer preguntas

Contexto

En Buchinger, los pacientes siguen tratamientos terapéuticos supervisados por un equipo médico.

Durante el tratamiento, los médicos necesitan entender el estado clínico del paciente en cada momento. Para ello, utilizan una herramienta interna que les muestra:

  • resultados de laboratorio
  • observaciones clínicas diarias
  • señales relevantes para la toma de decisiones

Estos datos no provienen de un único sitio. Llegan desde distintos sistemas externos y en distintos momentos.

El sistema interno debe construir una visión clara, consistente y útil para el equipo médico.


Objetivo

Construir una pequeña parte de este sistema que permita:

  • trabajar con datos clínicos de distintas fuentes
  • generar un análisis clínico actual de un paciente
  • entender la evolución durante el tratamiento
  • manejar situaciones imperfectas (datos incompletos, correcciones, cambios)

Arquitectura de la kata

         ┌──────────────────────────┐
         │   Médico / Equipo        │
         │   (HTTP client)          │
         └────────────┬─────────────┘
                      │
                      ▼
    ┌─────────────────────────────────────┐
    │  clinical-analysis  (puerto 3000)   │  ◀── aquí trabajas
    │                                     │
    │  GET /patients/:id/clinical-        │
    │       analysis/current              │
    │  GET /patients/:id/clinical-        │
    │       analysis/timeline             │
    │                                     │
    │  Arquitectura hexagonal + DDD       │
    │  TypeScript + Express + Prisma      │
    └──────┬──────────────────┬───────────┘
           │                  │            ┌───────────┐
           ▼                  ▼            │ Postgres  │
 ┌───────────────────┐ ┌──────────────────┐│  :5432    │
 │ laboratory-api    │ │ observations-api ││           │
 │   (puerto 3001)   │ │   (puerto 3002)  │└─────┬─────┘
 │                   │ │                  │      │
 │ Fuente 1 —        │ │ Fuente 2 —       │◀─────┘ (Prisma)
 │ Laboratory        │ │ Treatment        │
 │ Results           │ │ Observations     │
 └───────────────────┘ └──────────────────┘
     ya implementada        ya implementada

¿Qué hay en este repositorio?

  • apps/clinical-analysis — el servicio interno donde trabajarás. Tiene scaffolding con arquitectura hexagonal + DDD, Express, Prisma conectado a Postgres y clientes HTTP para las dos fuentes externas. Los endpoints del enunciado no están implementados: ese es tu trabajo.
  • apps/laboratory-api — servicio externo ya implementado que expone la Fuente 1. No necesitas tocarlo.
  • apps/observations-api — servicio externo ya implementado que expone la Fuente 2. No necesitas tocarlo.
  • postgres — base de datos disponible para que la uses como consideres (cache, histórico, señales, etc.).

Arranque rápido

Requisitos: Docker y Docker Compose.

docker-compose up --build

Eso levanta:

Servicio URL Descripción
clinical-analysis http://localhost:3000 El servicio donde trabajas
laboratory-api http://localhost:3001 Fuente 1 (Laboratory Results)
observations-api http://localhost:3002 Fuente 2 (Treatment Observations)
postgres localhost:5432 kata / kata / clinical_analysis

Comprobación rápida:

curl http://localhost:3000/health
curl http://localhost:3001/health
curl http://localhost:3002/health

💡 Una colección completa de comandos curl para explorar las fuentes y cada escenario por paciente está en docs/exploring.md.


Fuentes de datos disponibles

Las tienes ya montadas. No necesitas implementarlas, solo consumirlas.

📡 Fuente 1 — Laboratory Results (http://localhost:3001)

GET /v1/laboratory-results?patientRef={patientRef}[&treatmentRef={treatmentRef}]

Devuelve una lista de informes de laboratorio:

[
  {
    "patient_ref": "PAT-001",
    "treatment_ref": "TR-2026-001",
    "sample_taken_at": "2026-05-12T08:30:00Z",
    "results": {
      "glucose_mg_dl": 68,
      "ketones_mmol_l": 1.2,
      "crp_mg_l": 4.8,
      "sodium_mmol_l": 139
    },
    "reported_at": "2026-05-12T10:15:00Z"
  }
]

La v2 de esta fuente también existe (/v2/laboratory-results). La usarás en la Parte 6.

📡 Fuente 2 — Treatment Observations (http://localhost:3002)

GET /observations?patientId={patientId}[&treatmentId={treatmentId}]

Devuelve una lista de observaciones:

[
  {
    "patient_id": "PAT-001",
    "treatment_id": "TR-2026-001",
    "observed_at": "2026-05-12T09:00:00Z",
    "vitals": {
      "systolic_bp": 96,
      "diastolic_bp": 61,
      "heart_rate_bpm": 88
    },
    "symptoms": ["DIZZINESS", "FATIGUE"],
    "fluid_intake_ml": 1200
  }
]

Pacientes disponibles en las fuentes

Todos los pacientes tienen datos suficientes para trabajar. Cada uno cubre un escenario distinto:

Patient ID Treatment ID Escenario útil para...
PAT-001 TR-2026-001 caso normal, varios puntos en el tiempo (Parte 1, 2, 3)
PAT-002 TR-2026-002 CLINICAL_RISK_REVIEW_REQUIRED (hipoglucemia + mareo)
PAT-003 TR-2026-003 FASTING_EVOLUTION_EXPECTED (cetosis + glucosa normal)
PAT-004 TR-2026-004 solo laboratorio, sin observaciones (Parte 4)
PAT-005 TR-2026-005 solo observaciones, sin laboratorio (Parte 4)
PAT-006 TR-2026-006 contiene correcciones de resultados previos (Parte 5)

🚧 Parte 1 — Estado clínico actual

Objetivo

Construir una forma de obtener el estado clínico actual de un paciente combinando ambas fuentes.

Debes implementar

GET /patients/{patientId}/clinical-analysis/current

Debe devolver algo que permita ver:

  • últimos datos de laboratorio relevantes
  • últimas observaciones disponibles
  • una vista unificada del estado del paciente

El formato de la respuesta es libre.

Importante

  • Los datos vienen de dos fuentes distintas
  • Pueden tener timestamps diferentes
  • No siempre llegan al mismo tiempo

🧠 Parte 2 — Interpretación clínica

Objetivo

Añadir señales clínicas basadas en reglas de negocio.

Debes implementar

Una lista de clinicalSignals dentro del análisis actual.

Reglas de negocio

1. Glucosa baja

glucose < 70 mg/dL
→ LOW_GLUCOSE

2. Cetosis presente

ketones >= 0.5 mmol/L
→ KETOSIS_PRESENT

3. Hipotensión

systolic < 90 OR diastolic < 60
→ LOW_BLOOD_PRESSURE

4. Posible deshidratación

fluidIntake < 1500 ml
AND symptoms contiene DIZZINESS
→ POSSIBLE_DEHYDRATION

5. Riesgo clínico

LOW_GLUCOSE
AND symptoms contiene DIZZINESS
→ CLINICAL_RISK_REVIEW_REQUIRED

6. Evolución esperada del ayuno

KETOSIS_PRESENT
AND glucose entre 70 y 100
AND NO hay riesgo clínico
→ FASTING_EVOLUTION_EXPECTED

⏱ Parte 3 — Evolución del paciente

Objetivo

Permitir ver cómo evoluciona el paciente durante el tratamiento.

Debes implementar

GET /patients/{patientId}/clinical-analysis/timeline

Debe permitir ver:

  • análisis en orden temporal
  • datos disponibles en cada momento
  • señales clínicas en cada punto

Importante

  • Los datos pueden venir en momentos distintos
  • No siempre hay laboratorio y observación al mismo tiempo

🩹 Parte 4 — Datos incompletos

Objetivo

El sistema debe comportarse de forma razonable cuando falta información.

Ejemplos

  • solo hay laboratorio
  • solo hay observaciones
  • timestamps no coinciden
  • una fuente no responde

Debes decidir e implementar

  • qué mostrar
  • cómo evitar errores
  • cómo mantener una experiencia útil para el médico

✏️ Parte 5 — Correcciones

Objetivo

Gestionar cambios en datos ya recibidos.

Escenario

El laboratorio corrige un resultado previo (mismo sample_taken_at, distinto reported_at):

{
  "sample_taken_at": "2026-05-12T08:30:00Z",
  "results": { "glucose_mg_dl": 74 },
  "reported_at": "2026-05-12T12:45:00Z"
}

El paciente PAT-006 ya tiene este tipo de correcciones en la fuente.

Debes decidir e implementar

  • qué dato se considera el actual
  • qué pasa con el histórico
  • qué pasa con señales ya calculadas

🔀 Parte 6 — Cambio en una fuente

Escenario

La fuente de laboratorio cambia su formato. La nueva versión está disponible en:

GET /v2/laboratory-results?patientId={patientId}[&treatmentId={treatmentId}]

Devuelve algo como:

{
  "patientId": "PAT-001",
  "treatmentId": "TR-2026-001",
  "sample": { "takenAt": "2026-05-12T08:30:00Z" },
  "biomarkers": [
    { "code": "GLUCOSE",  "value": 740, "unit": "mg/L" },
    { "code": "KETONES",  "value": 1.2, "unit": "mmol/L" }
  ],
  "reportedAt": "2026-05-12T12:45:00Z"
}

Debes

Adaptar tu sistema para que el análisis clínico siga funcionando.


Trabajando con el servicio clinical-analysis

# Levantar todo
docker-compose up --build

# Solo la base de datos + las fuentes (para correr clinical-analysis en local con hot reload)
docker-compose up postgres laboratory-api observations-api

# Dentro de apps/clinical-analysis, en local:
cd apps/clinical-analysis
npm install
npm run prisma:generate     # genera el cliente Prisma
npm run prisma:migrate      # (opcional) crea tablas si añades modelos
npm run dev                 # arranca en modo watch

La estructura de apps/clinical-analysis sigue arquitectura hexagonal:

apps/clinical-analysis/src/
├── domain/              ← reglas y entidades puras del dominio (sin framework)
├── application/         ← casos de uso y puertos (interfaces)
│   └── ports/           ← LaboratoryResultsPort, TreatmentObservationsPort
└── infrastructure/      ← adaptadores, HTTP, persistencia, config
    ├── adapters/        ← clientes a las fuentes externas
    ├── http/            ← Express routes & controllers
    └── persistence/     ← Prisma client

Los puertos a las fuentes externas ya están definidos; los adaptadores HTTP ya están implementados. Puedes inyectarlos en tus casos de uso directamente.


Licencia

Uso interno de Code Sherpas para el proceso de selección de Buchinger.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors