Vitals  /  Architecture

Architecture

Vitals follows a medallion lifecycle (bronze → silver → gold) with a healthcare layer overlaid — the part a generic ETL project doesn't have.

● Bronze · raw & messy
FHIR · Claims · Wearables (Kafka) · PRO · Notes → Delta bronze
● Silver · de-identified
De-id → flatten → standardize codes → OMOP CDM → DQ contracts
● Gold · three stores
Analytics marts · Feature store · Vector index → MLflow + RAG demo

Why three gold stores

Analytics, classical ML, and LLM/RAG need different shapes of the same clean data:

The healthcare layer

De-identification at silver
PHI is tagged and access-gated at bronze; silver is the de-identified boundary — HIPAA Safe Harbor (drop the 18 identifier types) plus per-patient date-shifting to preserve temporal order. Everything downstream reads only de-identified data.

Production deployment

The medallion runs two ways by design: clone-and-run on DuckDB (no creds, no network, no Spark cluster — the reproducible baseline any reviewer can run), and as a scheduled Databricks serverless job. A Databricks Asset Bundle ships the full pipeline — medallion_ingestgold_dbtdrift_monitor. Verified TERMINATED SUCCESS; bronze = 28,816 rows, silver = 27,402.

terminal
$ make setup && make run # DuckDB, no creds $ make bundle-deploy # ship serverless job $ make dq # 14/14 Great Expectations

The wearable stream reads from a real local Kafka broker (Docker, single-node KRaft), not just a file source. Parity is proven: make stream-parity runs both the file and Kafka paths through the shared clean_wearables transform and asserts identical cleaned output (15,169 events, file == kafka).

Tooling

StageTool
OrchestrationAirflow
Bronze ingestPySpark; Spark Structured Streaming (Kafka)
StorageDelta on Databricks (ACID, schema evolution, time travel)
Silver → Golddbt (staging → intermediate → marts)
Data qualitydbt tests + Great Expectations
Feature storeFeast
Vector DBpgvector
Serving / monitoringMLflow + drift detection
Production deployDatabricks Asset Bundle · scheduled serverless job
IaCTerraform