Qadra Architecture
C4 Level 1 — System Context
Who uses Qadra and what does it talk to.
flowchart TB
user["fa:fa-user Tenant User<br/><i>Owner, admin, or member</i>"]
admin["fa:fa-user-shield Super Admin<br/><i>Cross-tenant platform operator</i>"]
subgraph platform["Qadra Platform"]
qadra["Multitenant Workload Orchestration<br/><i>Agents perform tasks · produce artifacts · ingest knowledge</i>"]
end
subgraph external["External Services"]
direction LR
openrouter["OpenRouter<br/><i>LLM inference</i><br/>Claude · GPT · Llama"]
smtp["SMTP2GO<br/><i>Email delivery</i>"]
minio["S3 / MinIO<br/><i>Object storage</i>"]
end
user -->|"Workloads, agents,<br/>flows, conversations"| qadra
admin -->|"Create tenants,<br/>manage users"| qadra
qadra -->|"LLM completions<br/>+ embeddings"| openrouter
qadra -->|"Verification, invite,<br/>notification emails"| smtp
qadra -->|"File upload<br/>/ download"| minio
style platform fill:#0d1117,stroke:#58a6ff,stroke-width:2px
style external fill:#1a1a2e,stroke:#30363d
C4 Level 2 — Container Diagram
What's inside the Qadra platform.
flowchart TB
user["fa:fa-user Tenant User<br/><i>Browser</i>"]
subgraph platform["Qadra Platform"]
direction TB
subgraph frontend["Frontend"]
spa["Web SPA<br/><i>React · Vite · Tailwind</i><br/>:5173"]
end
subgraph gateway_layer["Gateway"]
gateway["API Gateway<br/><i>Node.js · Express</i><br/>:4000<br/>JWT auth · CORS · HTTP→NATS"]
end
nats{{"fa:fa-arrows-alt NATS<br/><i>Request-Reply Bus</i><br/>:4222"}}
subgraph services["Services"]
direction LR
core["Rust Core<br/><i>Truth layer</i><br/>SPO index · ingestion<br/>flow executor · auth"]
agent["Python Agent<br/><i>Intelligence layer</i><br/>LLM orchestration<br/>workload execution"]
end
subgraph data["Data Stores"]
direction LR
postgres[("PostgreSQL<br/><i>pgvector</i><br/>Source of truth")]
mongodb[("MongoDB<br/>Audit traces")]
redis[("Redis<br/>Cache · streams")]
end
end
subgraph external["External Services"]
direction LR
openrouter["OpenRouter<br/><i>LLM API</i>"]
minio["MinIO<br/><i>S3 storage</i>"]
smtp["SMTP2GO<br/><i>Email</i>"]
end
user -->|"HTTPS"| spa
spa -->|"HTTPS"| gateway
gateway <-->|"publish / request"| nats
nats <-->|"subscribe / reply"| core
nats <-->|"subscribe / reply"| agent
core --> postgres
core -.-> mongodb
core --> redis
gateway --> minio
core -->|"HTTPS"| openrouter
agent -->|"HTTPS"| openrouter
core -->|"HTTPS"| smtp
style platform fill:#0d1117,stroke:#58a6ff,stroke-width:2px
style frontend fill:#161b22,stroke:#30363d
style gateway_layer fill:#161b22,stroke:#30363d
style services fill:#161b22,stroke:#30363d
style data fill:#161b22,stroke:#30363d
style external fill:#1a1a2e,stroke:#30363d
C4 Level 3 — Rust Core Components
What's inside the Rust Core container.
flowchart TB
NATS["fa:fa-envelope NATS Bus"]
subgraph core["Rust Core"]
direction TB
nats_svc["NATS Service<br/><i>8 wildcard handlers</i>"]
subgraph handlers["Request Handlers"]
direction LR
h_epist["epistemic.*<br/>KG queries, ingestion"]
h_work["workload.do.*<br/>CRUD + stage ops"]
h_auth["auth.*<br/>Login, register, tokens"]
h_flow["flow.do.*<br/>CRUD + execution"]
h_email["email.*<br/>Send + templates"]
h_admin["admin.*<br/>Super admin ops"]
end
subgraph engines["Engines"]
direction LR
ingestion["Ingestion Pipeline<br/><i>analyzer → extractor → embedder</i>"]
flow_exec["Flow Executor<br/><i>graph runner, 13 node types</i>"]
epistemic["Epistemic Core<br/><i>competence, verification, curvature</i>"]
end
subgraph infra["Infrastructure"]
direction LR
container["Service Container<br/><i>IoC, trait wiring</i>"]
observer["NATS Observer<br/><i>catch-all audit trail</i>"]
email_svc["Email Service<br/><i>SMTP2GO + Handlebars</i>"]
end
nats_svc --> handlers
h_epist --> ingestion
h_epist --> epistemic
h_flow --> flow_exec
h_email --> email_svc
end
NATS <--> nats_svc
observer -.->|"fire & forget"| MongoDB[(MongoDB)]
container --> PostgreSQL[(PostgreSQL)]
ingestion --> PostgreSQL
style core fill:#0d1117,stroke:#58a6ff,stroke-width:2px
style handlers fill:#161b22,stroke:#30363d
style engines fill:#161b22,stroke:#30363d
style infra fill:#161b22,stroke:#30363d
Data Flow — Document Ingestion
flowchart LR
A[Agent proposes document] -->|NATS: propose_document| B[documents table<br/>status: pending_approval]
B --> C{Human reviews}
C -->|Approve| D[stamps approved_by + approved_at]
C -->|Reject| E[stamps rejected_by + reason]
D -->|async tokio::spawn| F[Ingestion Pipeline]
F --> G[LLM Analyzer<br/>Spo / Both / Discard]
G -->|Spo| H[LLM Extractor<br/>SPO triples]
G -->|Both| H
G -->|Both| I[Chunker + Embedder<br/>vector chunks]
H --> J[(spo_nodes + spo_triples)]
I --> K[(pgvector embeddings)]
H --> L[document_triples<br/>provenance links]
I --> M[document_chunks<br/>provenance links]
Data Flow — Workload Execution
flowchart LR
A[Client] -->|NATS: workload.execute| B[Python Agent]
B --> C[For each pipeline stage]
C --> D[Get forwarded context<br/>from prior stages]
D --> E[LLM selects best agent]
E --> F[Create task<br/>via NATS to Rust Core]
F --> G[LLM executes with<br/>agent persona + context]
G --> H[Complete task + create artifact<br/>via NATS to Rust Core]
H --> I[Record stage result<br/>advance to next stage]
I --> C
NATS Subject Map
flowchart TB
subgraph "Tenant-Scoped"
E["qadra.{tid}.epistemic.*<br/>KG queries, ingestion, attribution"]
W["qadra.{tid}.workload.do.*<br/>Workload/task/artifact CRUD"]
F["qadra.{tid}.flow.do.*<br/>Flow CRUD + execution"]
end
subgraph "Tenant-Less"
AU["qadra.auth.*<br/>Login, register, tokens, invites"]
EM["qadra.email.*<br/>Send, templates, logs"]
AD["qadra.admin.*<br/>Super admin operations"]
AUD["qadra.audit.*<br/>Audit log queries"]
end
subgraph "Observer"
OB["qadra.><br/>Catch-all → MongoDB"]
end