Architecture: Simple Stack, Real Integrations¶
5 Docker services. 12 integration points. Zero stubs.
System diagram¶
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#1e293b', 'primaryTextColor': '#f8fafc', 'lineColor': '#64748b', 'fontSize': '13px'}} }%%
graph TB
subgraph CLIENT ["<b>Client</b>"]
Browser["<b>Browser</b><br/>React + Tailwind + Vite"]
end
subgraph GATEWAY ["<b>Gateway</b>"]
Nginx["<b>Nginx</b><br/>:3080"]
end
subgraph CORE ["<b>Application Core</b>"]
API["<b>FastAPI</b><br/>:8000"]
LG["<b>LangGraph</b><br/>8-node Clarifier"]
end
subgraph DATA ["<b>Data Layer</b>"]
PG["<b>Postgres 16</b><br/>OLTP + metrics_catalog"]
Redis["<b>Redis 7</b><br/>cache + pub/sub"]
end
subgraph AI ["<b>AI & Analytics</b>"]
Bedrock["<b>AWS Bedrock</b><br/>Sonnet 4.6 / Opus 4.7"]
Databricks["<b>Databricks</b><br/>SQL Warehouse"]
end
subgraph OBS ["<b>Observability</b>"]
Langfuse["<b>Langfuse</b><br/>LLM tracing"]
end
Browser -->|"HTTP + SSE + WS"| Nginx
Nginx --> API
API --> LG
API --> PG
API --> Redis
API --> Bedrock
API --> Databricks
API -.->|"opt-in"| Langfuse
Redis -->|"pub/sub"| API
API -->|"WebSocket"| Browser
classDef clientNode fill:#3b82f6,stroke:#1d4ed8,color:#fff,stroke-width:2px,rx:10
classDef gatewayNode fill:#06b6d4,stroke:#0891b2,color:#fff,stroke-width:2px,rx:10
classDef coreNode fill:#6366f1,stroke:#4f46e5,color:#fff,stroke-width:2px,rx:10
classDef dataNode fill:#8b5cf6,stroke:#6d28d9,color:#fff,stroke-width:2px,rx:10
classDef aiNode fill:#f59e0b,stroke:#d97706,color:#1e293b,stroke-width:2px,rx:10
classDef obsNode fill:#64748b,stroke:#475569,color:#fff,stroke-width:1px,rx:10,stroke-dasharray:5 5
classDef clientBox fill:#eff6ff,stroke:#3b82f6,stroke-width:2px,color:#1e293b
classDef gatewayBox fill:#ecfeff,stroke:#06b6d4,stroke-width:2px,color:#1e293b
classDef coreBox fill:#eef2ff,stroke:#6366f1,stroke-width:2px,color:#1e293b
classDef dataBox fill:#f5f3ff,stroke:#8b5cf6,stroke-width:2px,color:#1e293b
classDef aiBox fill:#fffbeb,stroke:#f59e0b,stroke-width:2px,color:#1e293b
classDef obsBox fill:#f8fafc,stroke:#94a3b8,stroke-width:1px,color:#64748b,stroke-dasharray:5 5
class Browser clientNode
class Nginx gatewayNode
class API,LG coreNode
class PG,Redis dataNode
class Bedrock,Databricks aiNode
class Langfuse obsNode
class CLIENT clientBox
class GATEWAY gatewayBox
class CORE coreBox
class DATA dataBox
class AI aiBox
class OBS obsBox
12 real integrations¶
Every integration is implemented and tested. No stubs.
| # | Integration | What it does | Evidence |
|---|---|---|---|
| Redis 7 | KPI cache + pub/sub fan-out + widget data cache | Real-time dashboard ticks in <5s | |
| PostgreSQL 16 | OLTP + metrics catalog + dashboard layouts | Schema in db/init.sql |
|
| AWS Bedrock | Two-tier LLM — 4 call sites | Sonnet 4.6 (fast) + Opus 4.7 (reasoning) | |
| Databricks | Live SQL queries — 3 Asurion metrics | Real claim data, not synthetic |
| # | Integration | What it does | Evidence |
|---|---|---|---|
| LangGraph | 8-node Clarifier with HITL pause | Full state machine, streamed over SSE | |
| SSE | Streaming Clarifier progress | Multi-turn conversation over POST | |
| Docker Compose | 5 services orchestrated | Single make up — zero manual setup |
|
| Langfuse | LLM observability — opt-in tracing | Every Bedrock call traced with latency |
| # | Integration | What it does | Evidence |
|---|---|---|---|
| @babel/standalone | Browser-side TSX compilation | Sealed scope — React + Icons only | |
| sqlglot | SQL structural safety | 18 tests, 25 cases — SELECT-only enforced | |
| :material-numeric-11-circle:{ style="color: #3b82f6" } | WebSocket | Real-time dashboard KPI updates | Sub-second server push |
| :material-numeric-12-circle:{ style="color: #3b82f6" } | Eval Harness | LLM codegen quality gate | 7 static checks + tsc --noEmit |
One pattern, four protocols¶
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#1e293b', 'primaryTextColor': '#f8fafc', 'lineColor': '#64748b', 'fontSize': '13px'}} }%%
graph LR
subgraph PROTOCOLS ["<b>Protocol per Purpose</b>"]
direction TB
REST["<b>REST</b><br/>Dashboard CRUD<br/>Widget persistence"]
SSE["<b>SSE</b><br/>Clarifier multi-turn<br/>Streaming progress"]
WS["<b>WebSocket</b><br/>KPI updates<br/>Sub-second push"]
TOOL["<b>Tool-use JSON</b><br/>Bedrock calls<br/>Structured output"]
end
REST -->|"standard req/resp"| API2["<b>FastAPI</b>"]
SSE -->|"streaming POST"| API2
WS -->|"server push"| API2
TOOL -->|"no parsing needed"| API2
classDef restNode fill:#3b82f6,stroke:#1d4ed8,color:#fff,stroke-width:2px,rx:8
classDef sseNode fill:#8b5cf6,stroke:#6d28d9,color:#fff,stroke-width:2px,rx:8
classDef wsNode fill:#22c55e,stroke:#15803d,color:#fff,stroke-width:2px,rx:8
classDef toolNode fill:#f59e0b,stroke:#d97706,color:#1e293b,stroke-width:2px,rx:8
classDef apiNode fill:#6366f1,stroke:#4f46e5,color:#fff,stroke-width:3px,rx:10
classDef protocolBox fill:#f8fafc,stroke:#94a3b8,stroke-width:2px,color:#1e293b
class REST restNode
class SSE sseNode
class WS wsNode
class TOOL toolNode
class API2 apiNode
class PROTOCOLS protocolBox
Why this matters
Each protocol is chosen for a reason — not bolted on. The same Event Context AI Action pattern works for claims, fraud, inventory, and retention. The architecture doesn't change — just the events and reason codes.
Speaker notes (45-60s)
- Point to the system diagram: "Five Docker services. Twelve real integrations. No stubs."
- Use the tabbed integration tables — click through Infrastructure / Application / Frontend. Don't read every row; let the count speak.
- Emphasize the protocol diagram: "REST for CRUD, SSE for the Clarifier, WebSocket for real-time, Bedrock tool-use for structured LLM output. Each protocol chosen for a reason."
- Land on the key line: "Same pattern works for claims, fraud, inventory, retention. The architecture doesn't change — just the events and reason codes."