Canonical source: docs/claude/labs.md. This page is generated by docs/scripts/sync-handbook.mjs. Edit the source file in the repo; changes appear here on the next build.
Labs System
The labs system spans lab ordering, document upload, AI analysis, registry management, and visualization.
End-to-End Lab Flow
- Ordering (Junction Health): Test catalog -> Lab packages -> Place order
- Upload: Upload PDF/Image -> Text extraction -> AI analysis
- Storage:
labscollection,documentLinks,documentSummaries - Display: Client summary, Labs tab, Copilot access
Lab Ordering (Junction Health)
Integration: functions_junction.py
| Function | Purpose |
|---|---|
junction_get_test_catalog | Fetch available lab tests |
junction_create_lab_package | Create saved test bundle |
junction_order_test | Order specific tests for patient |
junction_order_from_package | Order from saved package |
junction_get_orders | List orders for patient |
junction_get_results | Fetch results for order |
junction_webhook | Handle order/result updates |
Collections:
clinicsv2/{clinic}/lab_orders/{id}- Order recordsclinicsv2/{clinic}/lab_packages/{id}- Saved test bundlesclinicsv2/{clinic}/config/junction- API key configuration
Lab Marketplace Configuration
UI: Basis Flow Web Marketplace -> Labs Tab (basisflow-web/app/(main)/marketplace/page.tsx)
Features:
- Test catalog browsing with search
- Create/edit lab packages (saved test bundles)
- Enable/disable Junction integration per clinic
- API key configuration
Lab Upload & Analysis
Document Processing Flow:
- Staff uploads PDF/image via ImportLabModal
- File stored in Cloud Storage
analyze_document_summaryextracts text (OCR if needed)DocumentProcessorruns AI analysis:- Pattern matching for common lab values (regex)
- AI analysis for complex/unclear values
- Confidence scoring for extracted data
- Extracted values stored in
labscollection - Summary stored in
documentSummariesfor Copilot
Key Files:
functions_ai_documents.py- Document upload/analysis entry pointdocument_processor.py- Core extraction logicfunctions_lab_analysis.py- Lab-specific analysisfunctions_transcriber_replacement.py- Legacy lab analysis functions
Analysis Model:
class ExtractedDataPoint:
field_name: str # e.g., "ldl_cholesterol"
value: float # e.g., 145.0
unit: str # e.g., "mg/dL"
confidence: float # 0.0-1.0
source_text: str # Original text snippet
health_type: str # Canonical metric key
timestamp: datetime # Sample collection date
One-source registry + verdict engine (updated 2026-07-18 — #386/#392)
The current source of truth is a single generated registry that all surfaces read (no more per-surface drift):
generated/lab_registry.json(~800+ analytes) is generated bytools/build_lab_registry.pyfrom the analyte sources, merging core-over-registry refRanges (age/gender-based), canonicalUnit, and unit conversions. It generates the frontend TS (tools/generate_lab_ts.py→basisflow-web/lib/lab-analytes-generated.ts) and the mobile Dart mirror, all CI-drift-gated (tools/validate_lab_maps.py,validate_lab_ranges.py) so generated output can't diverge from source.lab_verdict.pyis the ONE verdict engine.evaluate_verdict(analyte_key, value, unit, sex)→ in-range/out-of-range, using the unified registry.canonical_analyte_key()resolves aliases (lab_analyte_aliases.json) so a doc stored under a variant key still finds its range;_norm_unit()collapses cosmetic unit spellings while keeping genuinely-different units distinct (mmol/L ≠ mg/dL — the "HDL 3.9" guard). LOINC vialab_loinc_map.json.- Aliases + canonicalization at ingest: every ingestion path — AI-analyze (
functions_ai_documents.py), Junction (functions_junction.py), manual upload — canonicalizes the analyte key (one lab = one key, no duplicate graph series) and normalizes units (no mixed mmol/mg-dL on one graph). - Persist verdict at write (#392): the computed verdict is stored on the lab doc at write time so Atlas + the UI read the same verdict (Atlas parity). (NOTE 2026-07-18: committed to master but the ingestion functions may not be redeployed yet — verify live.)
- Lab values feed protocol efficacy: lab-type biomarkers on a protocol read from
users/{uid}/labs(analyteKey) — seeprograms-protocols.md→ "Lab-type biomarker routing (#6)". - Benchmarks: wearable/body-comp metric benchmarks (zone minutes WEEKLY, FFMI, VO2max) live alongside in
generated/metric_benchmarks.json(tools/generate_metric_benchmarks.py); lab reference ranges ingenerated/lab_reference_ranges_generated.json. Registry consumers: mobilefindBenchmarkForType, webbenchmark-defaults.ts. (Several of these generated artifacts + generators were deploy-held/uncommitted as of 2026-07-18 — the registry regeneration was half-landed; check git before trusting.)
Lab Registry (legacy endpoint)
The registry provides canonical definitions for lab analytes (names, units, reference ranges).
Endpoint: get_lab_registry (HTTP)
Response:
{
"analytes": {
"ldl_cholesterol": {
"display_name": "LDL Cholesterol",
"unit": "mg/dL",
"reference_low": 0,
"reference_high": 100
}
},
"panels": {
"lipid_panel": {
"display_name": "Lipid Panel",
"analytes": ["ldl_cholesterol", "hdl_cholesterol"]
}
}
}
Clinic Synonyms: Clinics can define their own mappings for non-standard lab names:
upsert_clinic_lab_synonyms- Update clinic-specific synonyms- Storage:
clinicsv2/{clinic}/settings/labSynonyms
Lab Visualization
Client Summary (ClientDetailPage.tsx -> SummaryTab):
- Groups labs by source document
- Shows count and out-of-range indicators
- Clicking navigates to Labs tab or document preview
Labs Tab (ClientDetailPage.tsx -> LabsTab):
- Lists all lab results by category
- Shows trend charts for individual analytes
- Reference range indicators (low/normal/high)
- Age/gender-aware reference ranges when available
- Import new labs modal
Data Sources:
clinicsv2/{clinic}/clinic_users/{uid}/labs- Individual lab valuesclinicsv2/{clinic}/clinic_users/{uid}/documentLinks- Source documents
Lab Data Model
interface LabResult {
id: string;
displayName: string; // "LDL Cholesterol"
value: number; // 145
unit: string; // "mg/dL"
referenceRange?: {
low?: number;
high?: number;
text?: string; // "Optimal: <100"
};
collectedAt: Timestamp; // Sample date
source?: {
documentId?: string; // Reference to source doc
type?: 'junction' | 'upload' | 'manual';
};
category?: string; // "Lipid Panel", "Metabolic", etc.
analyteKey?: string; // Canonical key from registry
}
Key Files
| File | Purpose |
|---|---|
functions_junction.py | Junction Health integration |
functions_ai_documents.py | Document upload/analysis |
document_processor.py | Lab value extraction |
metric_registry.py | Metric definitions |
basisflow-web/...ClientDetailPage.tsx | Labs visualization |
basisflow/...tab_labs.dart | Legacy Flutter labs tab |