|
| 1 | +# PostgresAI — C4 Architecture Model |
| 2 | + |
| 3 | +This directory holds the [C4 model](https://c4model.com/) for PostgresAI, an |
| 4 | +AI-native PostgreSQL observability platform (monitoring, health checks, and root |
| 5 | +cause analysis). |
| 6 | + |
| 7 | +The model is maintained in two complementary forms: |
| 8 | + |
| 9 | +| File | Purpose | |
| 10 | +|------|---------| |
| 11 | +| [`workspace.dsl`](./workspace.dsl) | **Source of truth.** [Structurizr DSL](https://docs.structurizr.com/dsl) describing people, systems, containers, components and their relationships. Renders all C4 levels and stays in sync as a single definition. | |
| 12 | +| `README.md` (this file) | GitHub-renderable [Mermaid](https://mermaid.js.org/syntax/c4.html) diagrams for quick reading without tooling. | |
| 13 | + |
| 14 | +The C4 model describes architecture at four levels of zoom: **System Context** |
| 15 | +(L1) → **Containers** (L2) → **Components** (L3) → Code (L4, left to the source). |
| 16 | + |
| 17 | +## How to view the Structurizr model |
| 18 | + |
| 19 | +```bash |
| 20 | +# Render/edit interactively with Structurizr Lite |
| 21 | +docker run -it --rm -p 8080:8080 \ |
| 22 | + -v "$(pwd)/docs/architecture:/usr/local/structurizr" \ |
| 23 | + structurizr/lite |
| 24 | +# then open http://localhost:8080 |
| 25 | +``` |
| 26 | + |
| 27 | +--- |
| 28 | + |
| 29 | +## Level 1 — System Context |
| 30 | + |
| 31 | +How PostgresAI fits among its users and the external systems it talks to. |
| 32 | + |
| 33 | +```mermaid |
| 34 | +C4Context |
| 35 | + title System Context — PostgresAI |
| 36 | +
|
| 37 | + Person(dba, "Engineer / DBA", "Runs health checks, reviews dashboards, resolves issues") |
| 38 | + Person(ai, "AI Coding Agent", "Claude Code, Cursor, Windsurf — consumes reports & MCP tools") |
| 39 | +
|
| 40 | + System(pgai, "PostgresAI", "AI-native PostgreSQL observability platform") |
| 41 | +
|
| 42 | + System_Ext(target, "Target PostgreSQL", "Databases being observed (self-hosted, RDS/Aurora, CloudSQL, Supabase)") |
| 43 | + System_Ext(console, "console.postgres.ai", "Managed cloud: UI, Issues API, report/file storage, auth") |
| 44 | + System_Ext(supabase, "Supabase Management API", "Executes SQL on Supabase databases") |
| 45 | + System_Ext(aws, "AWS / Amazon Managed Prometheus", "RDS/Aurora + managed metrics") |
| 46 | + System_Ext(llm, "LLM Provider", "Anthropic Claude / OpenAI GPT") |
| 47 | +
|
| 48 | + Rel(dba, pgai, "Runs checkups, views dashboards, manages issues") |
| 49 | + Rel(ai, pgai, "Reads reports, calls MCP tools") |
| 50 | + Rel(pgai, target, "Connects to & queries", "SQL") |
| 51 | + Rel(pgai, console, "Uploads reports, syncs issues, authenticates", "HTTPS") |
| 52 | + Rel(pgai, supabase, "Executes SQL", "HTTPS") |
| 53 | + Rel(pgai, aws, "Reads metrics", "HTTPS") |
| 54 | + Rel(ai, llm, "Analyzes JSON reports") |
| 55 | +
|
| 56 | + UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="2") |
| 57 | +``` |
| 58 | + |
| 59 | +--- |
| 60 | + |
| 61 | +## Level 2 — Containers |
| 62 | + |
| 63 | +The separately deployable/runnable units inside PostgresAI. The CLI delivers the |
| 64 | +zero-setup express checkup; the rest form the optional full monitoring stack |
| 65 | +(`docker-compose.yml` / Helm chart). |
| 66 | + |
| 67 | +```mermaid |
| 68 | +C4Container |
| 69 | + title Containers — PostgresAI |
| 70 | +
|
| 71 | + Person(dba, "Engineer / DBA") |
| 72 | + Person(ai, "AI Coding Agent") |
| 73 | +
|
| 74 | + System_Ext(target, "Target PostgreSQL") |
| 75 | + System_Ext(console, "console.postgres.ai") |
| 76 | + System_Ext(supabase, "Supabase Management API") |
| 77 | + System_Ext(aws, "Amazon Managed Prometheus") |
| 78 | +
|
| 79 | + System_Boundary(pgai, "PostgresAI") { |
| 80 | + Container(cli, "CLI", "Node.js / TypeScript", "Express checkup, stack install, prepare-db, auth (postgresai / pgai)") |
| 81 | + Container(mcp, "MCP Server", "Node.js / TypeScript", "Exposes Issues tools to AI agents") |
| 82 | + Container(reporter, "Reporter", "Python", "Generates 45+ structured health-check reports") |
| 83 | + Container(flask, "Monitoring Backend", "Python / Flask", "Query history + PromQL proxy API") |
| 84 | + Container(pgwPg, "pgwatch → Postgres", "Go", "Collects metrics into the Postgres sink") |
| 85 | + Container(pgwProm, "pgwatch → Prometheus", "Go", "Collects metrics into VictoriaMetrics") |
| 86 | + ContainerDb(vm, "VictoriaMetrics", "TSDB", "Prometheus-compatible metrics store") |
| 87 | + ContainerDb(sink, "Postgres Sink", "PostgreSQL 17", "Historical metrics & check data") |
| 88 | + Container(grafana, "Grafana", "Grafana 12", "13+ observability dashboards") |
| 89 | + Container(telemetry, "Telemetry Agent", "Node.js", "Hourly system telemetry") |
| 90 | + Container(pilot, "pg_index_pilot", "SQL / PL-pgSQL", "Autonomous index lifecycle") |
| 91 | + } |
| 92 | +
|
| 93 | + Rel(dba, cli, "Runs commands") |
| 94 | + Rel(dba, grafana, "Views dashboards", "HTTPS") |
| 95 | + Rel(ai, mcp, "Calls tools", "MCP/stdio") |
| 96 | +
|
| 97 | + Rel(cli, target, "Health-check & prepare-db SQL", "SQL") |
| 98 | + Rel(cli, console, "Uploads reports, syncs issues, auth", "HTTPS") |
| 99 | + Rel(cli, supabase, "Runs queries", "HTTPS") |
| 100 | + Rel(cli, reporter, "Triggers report generation") |
| 101 | + Rel(mcp, console, "Reads/writes issues", "HTTPS") |
| 102 | +
|
| 103 | + Rel(pgwPg, target, "Scrapes", "SQL") |
| 104 | + Rel(pgwProm, target, "Scrapes", "SQL") |
| 105 | + Rel(pgwPg, sink, "Writes metrics", "SQL") |
| 106 | + Rel(pgwProm, vm, "Writes metrics", "HTTP") |
| 107 | +
|
| 108 | + Rel(reporter, vm, "Reads metrics", "PromQL") |
| 109 | + Rel(reporter, sink, "Reads history", "SQL") |
| 110 | + Rel(reporter, aws, "Reads metrics", "HTTPS") |
| 111 | + Rel(reporter, console, "Uploads reports", "HTTPS") |
| 112 | +
|
| 113 | + Rel(flask, vm, "Proxies PromQL", "HTTP") |
| 114 | + Rel(flask, sink, "Reads query history", "SQL") |
| 115 | + Rel(grafana, vm, "Queries metrics", "PromQL") |
| 116 | + Rel(grafana, sink, "Queries history", "SQL") |
| 117 | + Rel(grafana, flask, "Calls backend API", "HTTP") |
| 118 | +
|
| 119 | + Rel(telemetry, console, "Posts telemetry", "HTTPS") |
| 120 | + Rel(pilot, target, "Manages indexes", "SQL") |
| 121 | +
|
| 122 | + UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1") |
| 123 | +``` |
| 124 | + |
| 125 | +--- |
| 126 | + |
| 127 | +## Level 3 — Components: CLI |
| 128 | + |
| 129 | +The CLI is the primary entry point and the most component-rich container |
| 130 | +(`cli/lib/*.ts`). |
| 131 | + |
| 132 | +```mermaid |
| 133 | +C4Component |
| 134 | + title Components — CLI |
| 135 | +
|
| 136 | + Person(dba, "Engineer / DBA") |
| 137 | + System_Ext(target, "Target PostgreSQL") |
| 138 | + System_Ext(console, "console.postgres.ai") |
| 139 | + System_Ext(supabase, "Supabase Management API") |
| 140 | +
|
| 141 | + Container_Boundary(cli, "CLI") { |
| 142 | + Component(cmd, "Command Dispatch", "postgres-ai.ts", "Parses commands/flags, orchestrates workflows") |
| 143 | + Component(checkup, "Checkup Engine", "checkup.ts", "Runs 45+ health checks, builds JSON reports") |
| 144 | + Component(checkupApi, "Checkup API Client", "checkup-api.ts", "Uploads/fetches reports") |
| 145 | + Component(init, "DB Init / prepare-db", "init.ts", "Creates monitoring role, schema, permissions") |
| 146 | + Component(instances, "Targets / Instances", "instances.ts", "Manages monitored targets") |
| 147 | + Component(issues, "Issues Client", "issues.ts", "Console Issues API CRUD") |
| 148 | + Component(auth, "Auth (OAuth2/PKCE)", "auth-server.ts, pkce.ts", "Login & API-key handling") |
| 149 | + Component(storage, "Storage Client", "storage.ts", "File upload/download") |
| 150 | + Component(sb, "Supabase Client", "supabase.ts", "Runs SQL via Supabase API") |
| 151 | + Component(cfg, "Local Config", "config.ts, util.ts", "~/.postgres-ai settings") |
| 152 | + } |
| 153 | +
|
| 154 | + Rel(dba, cmd, "Runs commands") |
| 155 | + Rel(cmd, checkup, "Invokes") |
| 156 | + Rel(cmd, init, "Invokes") |
| 157 | + Rel(cmd, instances, "Invokes") |
| 158 | + Rel(cmd, issues, "Invokes") |
| 159 | + Rel(cmd, auth, "Invokes") |
| 160 | +
|
| 161 | + Rel(checkup, target, "Runs SQL", "SQL") |
| 162 | + Rel(checkup, checkupApi, "Uploads report") |
| 163 | + Rel(checkup, cfg, "Reads settings") |
| 164 | + Rel(checkupApi, console, "HTTPS") |
| 165 | + Rel(init, target, "Creates role/schema", "SQL") |
| 166 | + Rel(issues, console, "HTTPS") |
| 167 | + Rel(auth, console, "OAuth2/PKCE", "HTTPS") |
| 168 | + Rel(storage, console, "Uploads files", "HTTPS") |
| 169 | + Rel(sb, supabase, "HTTPS") |
| 170 | +
|
| 171 | + UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1") |
| 172 | +``` |
| 173 | + |
| 174 | +--- |
| 175 | + |
| 176 | +## Level 3 — Components: Reporter |
| 177 | + |
| 178 | +```mermaid |
| 179 | +C4Component |
| 180 | + title Components — Reporter |
| 181 | +
|
| 182 | + System_Ext(aws, "Amazon Managed Prometheus") |
| 183 | + System_Ext(console, "console.postgres.ai") |
| 184 | + ContainerDb(vm, "VictoriaMetrics") |
| 185 | + ContainerDb(sink, "Postgres Sink") |
| 186 | +
|
| 187 | + Container_Boundary(reporter, "Reporter") { |
| 188 | + Component(gen, "Report Generators", "postgres_reports.py", "Per-check report logic (A/D/F/H/I/K/M/N series)") |
| 189 | + Component(schemas, "Report Schemas", "schemas/*.schema.json", "29 JSON Schemas validating output") |
| 190 | + } |
| 191 | +
|
| 192 | + Rel(gen, vm, "Reads metrics", "PromQL") |
| 193 | + Rel(gen, sink, "Reads history", "SQL") |
| 194 | + Rel(gen, aws, "Reads metrics", "HTTPS") |
| 195 | + Rel(gen, schemas, "Validates against") |
| 196 | + Rel(gen, console, "Uploads reports", "HTTPS") |
| 197 | +
|
| 198 | + UpdateLayoutConfig($c4ShapeInRow="2", $c4BoundaryInRow="1") |
| 199 | +``` |
| 200 | + |
| 201 | +--- |
| 202 | + |
| 203 | +## Maintaining this model |
| 204 | + |
| 205 | +- Treat `workspace.dsl` as the source of truth; update it when containers, |
| 206 | + components, or integrations change. |
| 207 | +- Keep the Mermaid diagrams above in sync for at-a-glance reading on GitHub. |
| 208 | +- Useful references: [c4model.com](https://c4model.com/), |
| 209 | + [Structurizr DSL docs](https://docs.structurizr.com/dsl), |
| 210 | + [Mermaid C4 syntax](https://mermaid.js.org/syntax/c4.html). |
0 commit comments