alirezaaminzadeh/clinical-trial-supply-site-allocation-optimizer
Clinical Trial Supply & Site Allocation Optimizer
Production-oriented MVP for exploring blinded clinical supply policies under uncertain recruitment. It combines deterministic, seeded NumPy Monte Carlo simulation with a transparent FEFO allocation heuristic.
Important: This is an unvalidated decision-support prototype, not a clinical, GxP-validated, IRT/RTSM, forecasting, or release system. Outputs require review by qualified clinical supply, quality, regulatory, and logistics personnel.
Architecture
src/clintrial_opt/domain: strict Pydantic data contracts.src/clintrial_opt/application: simulation, policy triggers, risk, FEFO allocation.src/clintrial_opt/api: FastAPI transport and safe validation errors.frontend: static mobile-first control tower served by unprivileged nginx.data: synthetic sample input only; it contains no patient or real trial data.schemas: exported JSON Schema.tests: domain, policies, expiry, reproducibility, API and blinding checks.
The backend has no published host port. Nginx is the sole ingress on port 80. Containers run without root privileges or Linux capabilities, with read-only filesystems, health checks, memory limits, and an internal-only backend network.
Run with Docker Desktop
Copy-Item .env.example .env
docker compose up --build -d
docker compose ps
docker statsOpen <http://localhost>. Stop with docker compose down. The same Compose file uses relative paths and runs on Linux Docker Engine without code changes.
Local development
py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[test]"
pytest -q
ruff check .
python -m clintrial_opt.export_schema
uvicorn clintrial_opt.api.main:app --reloadAPI
GET /api/health: liveness.GET /api/schema: request JSON Schema.GET /api/demo: evaluate the synthetic scenario.POST /api/optimize: validate and evaluate a supplied scenario.
The input contract includes trial dates/blinding, sites and inventory, depots, blinded kit type codes and lots, cold-chain lanes, demand assumptions, and uncertainty settings. Unknown fields are rejected. Site-facing output never maps kit codes to active/placebo or other treatment identity.
Generate schemas/optimization-request.schema.json with:
python -m clintrial_opt.export_schemaDecision semantics
- Monthly recruitment is sampled from a non-negative normal approximation using
numpy.random.default_rng(seed). The requested percentile over the horizon estimates risk. This distribution is illustrative and must be calibrated before real use. - Observed recruitment above 8 patients/month creates an action to move the next shipment 10 days earlier.
- Usable inventory below P95 four-week demand creates an emergency replenishment action.
- The target adds configurable safety-stock weeks. Allocation is deterministic: shortest eligible lane then FEFO lots, bounded by lane capacity.
- Lots below minimum remaining shelf life are unusable. Lanes must satisfy temperature, import, and site-license constraints.
- A same-country site-to-site transfer is advisory only when a high-risk recipient and a donor with substantial excess are found. Protocol, blinding, release, chain-of-custody, tax, QA, and regulatory approval remain mandatory.
- Stockout probability is the share of simulated horizon demand above current usable inventory. It is not a validated probability of a clinical event.
The MVP intentionally uses a lightweight heuristic. A future validated implementation can introduce Pyomo/HiGHS behind an application interface while retaining this deterministic fallback.
Limitations
- No patient-level data, database, authentication, audit trail, electronic signatures, country calendars, customs duration distributions, randomization schedule, kit dispensing schedule, returns/destruction, release status, temperature excursions, or protocol visit schedule.
- Normal demand is a simplifying approximation; correlations and recruitment ramp-up are not modeled.
- FEFO allocation does not split shipment records by per-lot quantity.
- Container controls reduce attack surface but do not replace TLS, a VPS firewall, authentication, image scanning, signed images, or orchestrator secret management.
