Quick reference for poking at the three services while preparing or running the session. Every command assumes the stack is up (docker compose up --build) and that jq is installed (it ships with Ubuntu — install with sudo apt install jq if missing).
clinical-analysis→ http://localhost:3000 (the app the candidate writes)laboratory-api→ http://localhost:3001 (Fuente 1)observations-api→ http://localhost:3002 (Fuente 2)
curl -s http://localhost:3000/health | jq # clinical-analysis
curl -s http://localhost:3001/health | jq # laboratory-api
curl -s http://localhost:3002/health | jq # observations-apicurl -s -w '\nHTTP %{http_code}\n' http://localhost:3000/patients/PAT-001/clinical-analysis/current
curl -s -w '\nHTTP %{http_code}\n' http://localhost:3000/patients/PAT-001/clinical-analysis/timeline# All lab reports for a patient (the default payload)
curl -s "http://localhost:3001/v1/laboratory-results?patientRef=PAT-001" | jq
# Just what matters: one line per report
curl -s "http://localhost:3001/v1/laboratory-results?patientRef=PAT-001" \
| jq '.[] | {sample: .sample_taken_at, reported: .reported_at, glucose: .results.glucose_mg_dl, ketones: .results.ketones_mmol_l}'
# Filter by treatment as well
curl -s "http://localhost:3001/v1/laboratory-results?patientRef=PAT-001&treatmentRef=TR-2026-001" | jq length
# Count reports per patient
for p in PAT-001 PAT-002 PAT-003 PAT-004 PAT-005 PAT-006; do
n=$(curl -s "http://localhost:3001/v1/laboratory-results?patientRef=$p" | jq length)
printf '%s → %s reports\n' "$p" "$n"
done# Same patient, new format — note: patientId, biomarkers[], glucose in mg/L (×10)
curl -s "http://localhost:3001/v2/laboratory-results?patientId=PAT-001" | jq '.[0]'
# Show just the biomarkers for the latest sample
curl -s "http://localhost:3001/v2/laboratory-results?patientId=PAT-001" \
| jq '.[-1] | {reportedAt, biomarkers}'
# Side-by-side v1 vs v2 for the same sample (notice the units)
curl -s "http://localhost:3001/v1/laboratory-results?patientRef=PAT-001" | jq '.[0].results'
curl -s "http://localhost:3001/v2/laboratory-results?patientId=PAT-001" | jq '.[0].biomarkers'curl -s "http://localhost:3002/observations?patientId=PAT-001" | jq
# Compact: symptoms + vitals by day
curl -s "http://localhost:3002/observations?patientId=PAT-002" \
| jq '.[] | {at: .observed_at, bp: "\(.vitals.systolic_bp)/\(.vitals.diastolic_bp)", symptoms, fluid_ml: .fluid_intake_ml}'
# Filter by treatment
curl -s "http://localhost:3002/observations?patientId=PAT-001&treatmentId=TR-2026-001" | jq length# PAT-001 → baseline (Parts 1-3): healthy fasting, full data for 4 days
curl -s "http://localhost:3001/v1/laboratory-results?patientRef=PAT-001" | jq 'map({sample_taken_at, g: .results.glucose_mg_dl, k: .results.ketones_mmol_l})'
curl -s "http://localhost:3002/observations?patientId=PAT-001" | jq 'map({observed_at, bp: "\(.vitals.systolic_bp)/\(.vitals.diastolic_bp)", symptoms})'
# PAT-002 → CLINICAL_RISK_REVIEW_REQUIRED: low glucose + DIZZINESS on 2026-05-13
curl -s "http://localhost:3001/v1/laboratory-results?patientRef=PAT-002" | jq 'map({sample_taken_at, g: .results.glucose_mg_dl})'
curl -s "http://localhost:3002/observations?patientId=PAT-002" | jq 'map({observed_at, bp: "\(.vitals.systolic_bp)/\(.vitals.diastolic_bp)", symptoms, fluid: .fluid_intake_ml})'
# PAT-003 → FASTING_EVOLUTION_EXPECTED: ketosis + glucose 70-100 + no risk
curl -s "http://localhost:3001/v1/laboratory-results?patientRef=PAT-003" | jq 'map({sample_taken_at, g: .results.glucose_mg_dl, k: .results.ketones_mmol_l})'
curl -s "http://localhost:3002/observations?patientId=PAT-003" | jq 'map({observed_at, symptoms})'
# PAT-004 → lab only, no observations (Part 4)
curl -s "http://localhost:3001/v1/laboratory-results?patientRef=PAT-004" | jq length
curl -s "http://localhost:3002/observations?patientId=PAT-004" | jq length # → 0
# PAT-005 → observations only, no lab (Part 4)
curl -s "http://localhost:3001/v1/laboratory-results?patientRef=PAT-005" | jq length # → 0
curl -s "http://localhost:3002/observations?patientId=PAT-005" | jq length
# PAT-006 → corrections (Part 5): same sample_taken_at, two reported_at
curl -s "http://localhost:3001/v1/laboratory-results?patientRef=PAT-006" \
| jq 'sort_by(.reported_at) | .[] | {sample_taken_at, reported_at, glucose: .results.glucose_mg_dl}'
# PAT-006 → show ONLY the corrected duplicate group
curl -s "http://localhost:3001/v1/laboratory-results?patientRef=PAT-006" \
| jq '[group_by(.sample_taken_at)[] | select(length > 1)][0]'curl -s "http://localhost:3001/v1/laboratory-results?patientRef=PAT-DOES-NOT-EXIST" | jq # []
curl -s "http://localhost:3002/observations?patientId=PAT-DOES-NOT-EXIST" | jq # []
# Required param missing → 400
curl -s -w '\nHTTP %{http_code}\n' http://localhost:3001/v1/laboratory-results
curl -s -w '\nHTTP %{http_code}\n' http://localhost:3002/observationsfor p in PAT-001 PAT-002 PAT-003 PAT-004 PAT-005 PAT-006; do
lab=$(curl -s "http://localhost:3001/v1/laboratory-results?patientRef=$p" | jq length)
obs=$(curl -s "http://localhost:3002/observations?patientId=$p" | jq length)
printf '%-8s lab=%s obs=%s\n' "$p" "$lab" "$obs"
donecurl -s URL | jq # pretty + coloured
curl -s URL | jq '.[0]' # first item
curl -s URL | jq '.[0:3]' # first 3
curl -s URL | jq 'length' # how many
curl -s URL | jq 'sort_by(.x)' # sort by field
curl -s -w '\n{"http_status":%{http_code}}\n' URL | jq -s # body + status code