React · TanStack · Tailwind
OAuth · PKCE · DCR
Every load-bearing layer is replaceable.
One data plane
Underneath the four hosts sits a small set of backing services. Every one is interchangeable at a config level.
- PostgreSQL — the single source of truth. Rows, workflow state, audit log, agent reflection memory, and retrieval chunks all live in the same instance. A standard database dump produces a portable backup of the entire stack. Continuous point-in-time recovery at five-minute granularity on managed Postgres today; the connection string is one configuration change away from RDS, Cloud SQL, or Supabase. Every multi-tenant table carries a tenant id and a Postgres row-level-security policy keyed on the request-scoped tenant setting.
- Vector search in the same Postgres. Retrieval and agent memory ride on the standard Postgres vector extension in the same instance. Reflection embeddings and upload chunks are stored as native vector columns, indexed for cosine search. The same per-row visibility gate that governs every SPA list endpoint governs the vector reads.
- S3-compatible object store — uploads and backups through a portable storage adapter. Any S3-compatible endpoint — AWS S3, Cloudflare R2, MinIO, Backblaze B2 — is one configuration change away. Browser uploads use presigned PUT URLs; bytes never traverse the application server.
- Redis — cache, rate limits, workflow-step claims, MFA pending-secret cache, and the upload-indexer queue drained by a single-consumer worker.
- OpenTelemetry backbone — vendor-neutral OTLP spans and metrics from every service. The exporter (Tempo, Honeycomb, Datadog, Grafana Cloud, AWS X-Ray) is a configuration choice.
Every load-bearing layer at the boundary is a public specification with more than one compatible implementation. See open standards for the full stance.
Isolated services with clean seams
Three stateless application services, each independently horizontally scalable.
- Core API — the authoritative surface. Serves the JSON API for the SPA, hosts the embedded LLM agent loop, and drives every write to Postgres and object storage. Reads shape metadata from the entity metadata layer on every request.
- MCP server — the Model Context Protocol surface for external AI clients. OAuth authorisation-code with mandatory PKCE and audience-bound tokens (RFC 8707). Zero authentication tools by design — credentials never travel as tool arguments.
- SPA bundles — three separately built browser artifacts (staff and tenant workspace, external client portal, embeddable widget) served by minimal static-content containers behind the reverse proxy.
Every service is stateless. Every service scales by adding replicas. Configuration flows via environment variables only, per Wiggins’s Twelve-Factor App from 2011. The MCP server is a thin pass-through to the API service layer — fixes belong in the API, and MCP inherits them. Every capability lands in exactly one place.
The takeaway
Four hosts. One data plane. Two services with one contract. Paired replicas rolling behind an active-health-probed round-robin. Every boundary that matters is a physical boundary; every backing service is portable at a config level. The code is the same across shared-tenancy, vanity-domain, and dedicated deployments — the deployment differs, the connection string differs, the application stays put.
This is the substrate technical buyers audit. Read for CTOs for the buyer-side view.