Skip to content

Repository files navigation

RadFlow

AI-powered radiology worklist & dictation cockpit — a unified workspace where radiologists manage their reading queue, view DICOM studies, dictate reports, and let AI draft the structured report — integrated with clinical systems via HL7 and DICOM.

Cockpit de worklist e ditado radiológico com IA — um espaço único onde radiologistas gerenciam a fila de leitura, visualizam estudos DICOM, ditam laudos e deixam a IA estruturar o rascunho — integrado a sistemas clínicos via HL7 e DICOM.

⚠️ Demo project / Projeto de demonstração. Synthetic patients and generated DICOM only. No real PHI, ever. / Somente pacientes sintéticos e DICOM gerado. Nenhum PHI real.

RadFlow journey: login → claim → dictate → AI draft with critical finding → sign → admin KPIs

Architecture / Arquitetura

flowchart TB
    web["React/Vite cockpit<br/>worklist · dictation · admin KPIs"]
    gw["api-gateway (NestJS)<br/>auth · RBAC · 403 audit · WS fan-out"]

    web -- "HTTPS + WebSocket (JWT)" --> gw

    subgraph services["Event-driven microservices"]
        wl["worklist-svc (NestJS + PG)<br/>queue · SLA · claim/sign<br/>audit · stats"]
        integ["integration-svc (NestJS)<br/>HL7 ORM in (MLLP) · ORU out<br/>Orthanc bridge · synthetic DICOM"]
        dict["dictation-svc (NestJS + PG)<br/>report draft → signed<br/>signing saga with worklist"]
        ai["report-ai-svc (Python/FastAPI)<br/>LLM draft · critical findings<br/>eval harness (Anthropic/OpenAI/stub)"]
    end

    gw -- "HTTP (X-User-*, traceparent)" --> wl & integ & dict
    dict -- "draft (HTTP)" --> ai
    dict -- "signing saga (HTTP)" --> wl

    nats[("NATS JetStream<br/>outbox → relay → durable consumers → DLQ")]
    wl <--> nats
    integ <--> nats
    dict <--> nats
    nats -- "events → WS" --> gw

    subgraph infra["Infrastructure"]
        pg[("PostgreSQL<br/>database per service")]
        pacs["Orthanc + OHIF<br/>PACS / viewer"]
        obs["OTel → Jaeger<br/>Prometheus → Grafana"]
    end

    wl -.-> pg
    dict -.-> pg
    integ -.-> pacs
Loading

Key patterns / Padrões centrais: rich domain aggregates (DDD tático), transactional outbox, optimistic locking, durable consumers with DLQ, append-only audit log (DB trigger), JWT + RBAC at the gateway, LLM eval harness with CI gate. Decisions are recorded in specs/ (ADRs 0001–0009).

Stack

NestJS/TypeScript · React 19 + Vite · PostgreSQL 16 · NATS JetStream · Python 3.12/FastAPI · Docker Compose · OpenTelemetry + Jaeger · Prometheus + Grafana · Orthanc + OHIF

Getting started

# full stack (13 containers)
docker compose up -d --build

# optional: real AI drafts (otherwise a deterministic stub is used)
AI_PROVIDER=anthropic ANTHROPIC_API_KEY=sk-... docker compose up -d report-ai
Surface URL Credentials
Cockpit (web) http://localhost:5173 ana/ana (radiologist) · admin/admin · tech/tech
API gateway http://localhost:3010/api/v1 JWT via POST /auth/login
Orthanc + OHIF http://localhost:8042
Jaeger (traces) http://localhost:16686
Grafana (dashboards RadFlow) http://localhost:3300 admin/admin
Prometheus http://localhost:9091

Feed it with synthetic HL7 orders (each one becomes a study + DICOM images in Orthanc):

pnpm --filter @radflow/integration run feeder -- --rate 20 --duration 60

Development

pnpm install
pnpm run build:packages   # shared → messaging → ddd → telemetry
pnpm run typecheck
pnpm test                 # unit + integration (integration uses Testcontainers: PG, NATS, Orthanc)
pnpm -r run test:e2e      # service-level e2e

Python service:

cd services/report-ai
uv sync
PYTHONPATH=src AI_PROVIDER=stub uv run pytest
PYTHONPATH=src AI_PROVIDER=stub uv run python -m report_ai.eval   # LLM eval harness (CI gate)

Engineering rules live in AGENTS.md. Tests are split into .spec.ts (unit), .int-spec.ts (Testcontainers) and .e2e-spec.ts.

Compliance story / Narrativa de conformidade

  • Append-only audit log per service — a database trigger rejects UPDATE/DELETE; every write use case records who/what/when/origin in the same transaction.
  • Denied write attempts (403 at the gateway) are audited too.
  • RBAC per route: technologist feeds orders, radiologist claims/dictates/signs, admin reads audit trails and KPIs.
  • Zero PHI: synthetic patients, generated DICOM, no audio ever leaves the browser (Web Speech API — see ADR 0006).

About

AI-powered radiology worklist & dictation cockpit — NestJS microservices, NATS JetStream, HL7/DICOM, Python LLM service. Demo project, zero PHI.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages