System shape & decided stack
A modular monolith with one deliberate satellite: the interface engine runs as its own process so instrument traffic never drops during a deploy. Every rule that touches a result is versioned data, not code.
Decided technology stack
| Layer | Choice | Notes |
|---|---|---|
| Frontend | Next.js (TypeScript) | One codebase; role-gated surfaces (lab ops, portals, admin) |
| Backend | Python · FastAPI | Modular monolith; split services only when scale forces it |
| Database | MySQL — schema-per-tenant | One database per tenant lab; isolation enforced at the data layer, never only in application code |
| Cache / queues | Redis | Sessions, rate limits, interface message queues, background jobs |
| Packaging | Docker | CI-gated deploys; running stack always equals main |
| Hosting | US region under HIPAA BAA | No real patient data exists anywhere until a Business Associate Agreement is signed |
Architecture
Architecture principles
Interface engine layer
Every external connection — analyzers (ASTM/HL7/POCT1-A), EHR feeds (HL7 v2 orders in, results out), reference-lab send-outs, public-health reporting — is an adapter behind a common interface with per-interface queues, retry, and a message log. No integration calls scattered through core services.
Rules engine layer
Reflex testing, auto-verification, delta checks, critical-value detection, and billing-rule checks are declarative, versioned rule sets evaluated server-side — never hardcoded per-test logic.
Lab-type configuration
Each tenant selects a lab profile (clinical/commercial, hospital, POL, toxicology, molecular, pathology, veterinary). The profile drives test-catalog defaults, workflow stages shown, server-enforced field rules, and page composition — profiles are reference data, extensible per lab.
Billing boundary
The LIS produces clean billable events (CPT-coded, diagnosis-linked, payer-attached); claim submission goes through a clearinghouse adapter behind a single BillingProvider interface — clearinghouse choice stays swappable.
Non-functional targets
| Target | Commitment |
|---|---|
| Availability | SLA 99.9% · p95 API latency < 300 ms · RPO ≤ 5 min / RTO ≤ 1 hr |
| Interface engine | No inbound analyzer/HL7 message ever dropped — queue-and-acknowledge with durable message log; instrument-to-portal turnaround < 30 s |
| Bench speed | Keyboard/scanner-first UX: accession a specimen (scan → verify → route) in < 5 s |
| Onboarding | POL self-serve onboarding under 1 day, including a starter test catalog |
| Inspection readiness | Any result's full chain of custody (order → collection → accession → runs → QC status → verification → report versions → deliveries) reconstructable from one screen |