Platform Architecture (Golden Copy)
Canonical, deck-facing architecture of record. Every external/marketing artifact (Platform deck, Security & Trust deck, website) must match this file. If the code and a slide disagree, this doc — verified against code — wins; update the slide.
| Owner | Classification | Status | Verified against code |
|---|---|---|---|
| Kris (product) · Raj (architecture) | Internal | Living | 2026-09-05 — blitz/src/ |
Why this exists. The prior source was a Z-drive doc (
FINAISSE-PLATFORM-ARCHITECTURE-v2.md, 2026-05-19) that had drifted from the code (esp. Finni tool maturity). From now the golden copy is git-managed here; the Z doc is superseded.
1. The platform in one picture (the "layer cake")
Slide-ready. Only shipped capability is unqualified; aspirational is marked ⚠.
CONNECTORS · IN API / AGENTS · OUT
Salesforce · Xero · Zoho Books REST Business API (:10001)
Google Drive · SharePoint · SFTP MCP server ⚠ (framework only, demo tool)
Email intake · Desktop / RemoteControl A2A "bring your own agent" ⚠ (planned)
│ ▲
▼ │
┌──────────────────────────────────────────────────────────────┐
│ APPLICATIONS (modules) │
│ Cash App · Collections* · Invoice (AP) · Journal · │
│ Reconciliation · Close Hub · FinHub (CFO aggregation view) │
├──────────────────────────────────────────────────────────────┤
│ CONTINUOUS INTELLIGENCE — Finni + agents │
│ Finni (6 domain agents + FinHub supervisor) · builder agents · │
│ 6 judge scorers · Doc-AI extraction (Gemini / DocAI) · │
│ Classical ML (scikit-learn, 12 services, dormant) · │
│ LLMs: Ollama (local, default) · OpenAI · Gemini │
├──────────────────────────────────────────────────────────────┤
│ ORCHESTRATION & DECISION ENGINES │
│ Temporal (TS + Python workers) · Rules engine + row-level │
│ config (matching_config / transformationflow) · │
│ DuckDB export→transform→import · doc-transform (Razor/excelrw, │
│ pdfwriter, templates, jsontransformer, scriptrunner) · │
│ events · websockets │
├──────────────────────────────────────────────────────────────┤
│ CONNECTED DATA SUBSTRATE (per tenant) │
│ FinBase shared schema + module schemas inside ONE tenant DB; │
│ DuckDB transform workspace; per-tenant object storage │
├──────────────────────────────────────────────────────────────┤
│ SECURE MULTI-TENANT FOUNDATION │
│ Dedicated PostgreSQL DB PER TENANT (cloned from a golden │
│ template) + dedicated buckets · JWT-bound tenant context · │
│ Tenant Manager / registry (mgmt.tm.tenant) · │
│ auto-provisioning Temporal workflow · stateless DI service plane│
└──────────────────────────────────────────────────────────────┘
* Collections = sub-module of Cash / AR (not a standalone package).
FinHub = cross-module aggregation controller (not a module triplet).2. Tenancy model — dedicated database per tenant (verified TRUE)
Genuinely database-per-tenant, not shared-schema-with-tenant_id.
- Registry:
mgmt.tm.tenantholds one row per tenant with a unique Postgresconnectionstring—packages/mgmt/mgmtd/prisma/models/mgmt.prisma('tenant specific database'). This registry DB is the one shared control-plane database. - Provisioning (automated, durable): creating a tenant fires a Temporal
provisionTenantworkflow (packages/mgmt/mgmta/controllers/mgmt/v1/tenant.controller.ts). Activities (packages/system/systemwf/src/activities/provisioning.ts):CREATE DATABASE "<db>" TEMPLATE "<golden-template>"(clones schema + baseline atomically) → create per-tenant object-storage buckets → flipisenabled=true; failure drops the DBWITH (FORCE). - Connection resolution:
libs/tenancy/src/services/tenanconnections.service.ts— per-tenant cache holding 8 Prisma clients built from that tenant's connection string (system, cash, closehub, coresystem, finbase, invoice, journal, reconciliation). "The connection string is the isolation boundary." - Within a tenant DB: further separated by Postgres schema (cash, closehub, coresystem, finbase, invoice, journal, reconciliation, sys). One physical DB, multiple schemas.
- Tenant binding: resolved per request from Host/subdomain (or
x-blitz-tenant-id, or signed OAuthstate), stamped into the JWT at login (signin.controller.ts, claimtenantId) and derived from the verified JWT on every authenticated request (systema/plugins/authenticator.ts).- ⚠ Security note: the register still tracks F-01 (tenant binding hardening) as an open P0 — the design binds every request; the enforcement needs the hardening in the security findings closed before this claim is stress-tested in a pen-test/DD.
- Dev/single-tenant:
TENANCY_ENABLED=falsecollapses to oneDATABASE_URL+ the all-zeros DEFAULT tenant, same code path.
Canonical sentence for decks: "Shared, stateless service plane (every request bound to a tenant context via signed JWT) + a dedicated PostgreSQL database and object store per tenant, cloned from a golden template." Do not say "schema-isolated" as the tenant boundary — that describes intra-DB layout, not the isolation model.
3. Component inventory (by layer, code-cited)
Control plane / shared services (Bun + Elysia, DI via libs/di):
- Tenant Manager —
packages/mgmt/mgmta(+ registrymgmt/mgmtd) - Business/Core API —
apps/api(:10001); mounts module controllers vialibs/appsloader - Management API —
apps/apimgmt(:9999) - System —
packages/system/systema(auth/JWT, users, fs, OAuth) +systemwf(provisioning, doc-process) - CoreSystem —
packages/finance/coresystem(jobqueue, extraction registry)
Orchestration: Temporal (real SDK) — worker apps/wfw (libs/wfw), client libs/wfc, PDF worker apps/wfwpdf; Python Temporal worker apps/classicml. Events apps/events (:10009) · websockets apps/ws (:10002, Finni chat streaming) · queue apps/queue (:10008).
Continuous Intelligence:
- Agent framework —
libs/agents(registryagentsregistry.ts),libs/agentsbase(LangChain/LangGraph, checkpointer, usage metering) - LLMs —
libs/agentsbase/src/models/modelConfig.ts: Ollama (local, default; lib defaultgemma4, Finni chat defaultqwen3), OpenAI, Google Gemini. See Intelligence — model/provider map for which model runs where. - Finni —
packages/finance/financeagents: 6 domain agents (cashapp, collections, invoice, journal, closehub, reconciliation) + a FinHub supervisor agent that LLM-classifies a query and routes to the 6 domain graphs (finni-agent/index.tsclassifyFinhubRoute) + 2 builder agents (graph-builder, grid-builder) - 6 judge scorers — cid, match, po-match, collection, gl-coding, remittance (+ shared harness) —
financeagents/src/agents/ - Classical ML —
apps/classicml(scikit-learn, 12 ML services — anomaly, classification, multiclass, regression, ranking, timeseries, clustering, survival, changepoint, dimreduction, profiling, recommendation — each with train + inference; dormant: no finance flow consumes them yet) - Doc-AI extraction —
libs/docai(Google DocAI + Gemini + LlamaIndex) - Agents server
apps/agents(:10013) · MCP serverapps/mcp(:10012) ⚠ framework only — demo tool, real tools not yet wired
Doc-transform: apps/excelrw (.NET Razor + DuckDB workspace, :10014) · apps/pdfwriter (:10011) · apps/templaterenderer (:10005) · apps/jsontransformer (:10004) · apps/rulesengine (:10006, libs/rulesengine) · apps/scriptrunner (:10003) · apps/email + apps/emailprocessor · apps/fs (:10010).
Integrations: libs/salesforce · xero · zohobooks · gdrive · sharepoint · sftp; remote exec apps/remotecontrol (:10016) + apps/desktop. ERP / SAP: a .NET BAPI proxy — apps/excelrw/BapiProxyService (:10017), a Temporal worker on taskqueue-system-sap, driven by systemwf workflows BAPI_PO_GETDETAIL / BAPI_INCOMINGINVOICE_CREATE via systemwfp proxy activities; invoice posting via invoicea/…/sapinvoice.service.ts.
Per-tenant data plane: dedicated Postgres DB (schemas: cash, closehub, coresystem, finbase, invoice, journal, reconciliation, sys) + per-tenant S3/RustFS buckets; DuckDB as transform workspace (libs/duckdb).
4. Modules
Real triplets (*a API / *d Prisma / *wf Temporal): Cash App (finance/cash), Invoice (finance/invoice), Journal (finance/journal), Reconciliation (finance/reconciliation), Close Hub (finance/closehub); shared substrate FinBase (finbase); CoreSystem.
- Collections — has a
WELLKNOWN_APPSid and a full Finni agent, but lives insidecash(controllers incasha, schema incashd/…/cashapp.prisma). Present as sub-module of Cash/AR. - FinHub — not a triplet; a cross-module CFO surface with two parts: (1) an aggregation controller in
libs/appsloader/src/finhub/(GET /api/o/finance/finhub/v1/cfo-summary,cfo.signals.ts— pure functions over module cards, no persisted read-model), and (2) a FinHub Finni supervisor agent (financeagents/.../finhub-composite-tools.ts,finhub-composite-systemprompt.md) that classifies a CFO query and dispatches to a domain agent's graph. Real, and now more than thin on the Finni side.
5. Engines & pipeline
- Decision model — "rules · patterns · Finni": rules engine
libs/rulesengine; row-level configmatching_config/transformationflowinfinbase; DuckDB export→transform→import (CashApp + Recon); classical ML inclassicml. Principle holds in code: rules decide, LLM judges score candidates — they do not post. - Pipeline — Ingest → Extract → Transform → Decide → Post → Evidence: the
rundocprocessorchestrator (dispatcher → generic extraction → per-doctype Temporal workflows) + module*wfpackages.
6. Deck claim ledger (what is safe to state externally)
| Claim | Verdict |
|---|---|
| Dedicated PostgreSQL DB + object store per tenant, cloned from golden template | ✅ TRUE |
| Every request bound to a tenant context (JWT) | ✅ design TRUE — F-01 hardening open (don't over-claim "enforced" in security DD) |
| Shared, stateless service plane | ✅ TRUE (note: one shared control-plane registry DB, mgmt) |
| Workflow engine = Temporal (TS + Python) | ✅ TRUE |
| Finni across all six modules with tools | ✅ TRUE (supersedes old "0 tools for recon/journal/invoice/collections") |
| Classical ML (scikit-learn) in production | ✅ TRUE |
| Rules decide · LLM judges score · never posts | ✅ TRUE |
| MCP / A2A external agent surface | 🔜 IN BUILD — shipping soon (weeks out per product); label "coming soon", not "roadmap". Gated on F-01/F-11 (tenant binding / authz) — confirm those close before external exposure. |
| Collections is a standalone module | ❌ FALSE — sub-module of Cash |
| FinHub is a module triplet | ❌ FALSE — aggregation view |
| Fixed "14 Finni tools" / "22 apps" counts | ❌ STALE — don't cite fixed counts on slides |
Revision history
| Date | Change |
|---|---|
| 2026-09-15 | Count corrections (code-verified): Finni = 6 domain agents + FinHub supervisor (was "6 module agents"); 6 judge scorers (was 7); Classical ML = 12 services (was 15), flagged dormant; Ollama noted as the default provider; FinHub now carries a Finni supervisor agent. Added the ERP / SAP integration (BAPI proxy on :10017 / taskqueue-system-sap), previously omitted. Cross-links to the new Intelligence section. |
| 2026-09-05 | Initial golden copy — code-verified against blitz/src/; supersedes Z FINAISSE-PLATFORM-ARCHITECTURE-v2.md. |