Skip to content
Last updated: Sep 25, 2026

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.

OwnerClassificationStatusVerified against code
Kris (product) · Raj (architecture)InternalLiving2026-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.tenant holds one row per tenant with a unique Postgres connectionstring — 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 provisionTenant workflow (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 → flip isenabled=true; failure drops the DB WITH (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 OAuth state), stamped into the JWT at login (signin.controller.ts, claim tenantId) 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=false collapses to one DATABASE_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 (+ registry mgmt/mgmtd)
  • Business/Core API — apps/api (:10001); mounts module controllers via libs/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 (registry agentsregistry.ts), libs/agentsbase (LangChain/LangGraph, checkpointer, usage metering)
  • LLMs — libs/agentsbase/src/models/modelConfig.ts: Ollama (local, default; lib default gemma4, Finni chat default qwen3), 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.ts classifyFinhubRoute) + 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 server apps/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_APPS id and a full Finni agent, but lives inside cash (controllers in casha, schema in cashd/…/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 config matching_config / transformationflow in finbase; DuckDB export→transform→import (CashApp + Recon); classical ML in classicml. Principle holds in code: rules decide, LLM judges score candidates — they do not post.
  • Pipeline — Ingest → Extract → Transform → Decide → Post → Evidence: the rundocprocess orchestrator (dispatcher → generic extraction → per-doctype Temporal workflows) + module *wf packages.

6. Deck claim ledger (what is safe to state externally) ​

ClaimVerdict
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 ​

DateChange
2026-09-15Count 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-05Initial golden copy — code-verified against blitz/src/; supersedes Z FINAISSE-PLATFORM-ARCHITECTURE-v2.md.

Finaisse Internal — Confidential. Access-restricted; not for external distribution.