The AI lives inside the system, not glued to the front.

Wholix is a multi-tenant CRM & AI platform whose core decision is an architectural one: almost nothing is hard-coded. JSON Definitions describe WHAT, Processors decide HOW, data flows through. New capabilities ship as a definition, not as a release. That shape is exactly what modern LLMs produce reliably, which is why AI here is not a bolted-on chat window but the foundation.

Horizon  H2 2026 · forward-looking to H1 2027 Hosting  EU (eu-central-1) Source  product-architecture-deep-dive Version  0.1 (draft)
9
Services in production, EU-hosted
5
Authoring surfaces (the moat)
~20×
Faster: new CRM object in hours, not weeks
6
Stage delivery pipeline, gated
0
Shared hot paths across tenants
3
Independent scaling vectors
1
AI gateway, provider swap = config
100%
Infrastructure as code (Terraform)
Part II · The core principle →

Definition → Processor → Data. One pattern, everywhere.

Every non-trivial capability follows the same three-part shape. Once the processor is tested, new behaviour is just a new definition, not new code. That is the lever that compounds on every subsequent feature.

Definition
Describes the WHAT

A JSON document that captures intent: this object, this flow, this agent, this campaign. Versioned, diffable, reviewable like source code.

Processor
Decides the HOW

Runtime code that consumes documents of that shape. Tested once, thoroughly; every subsequent definition inherits that guarantee.

Data
Flows through

The actual customer records, messages and events processed against the definition.

// A new CRM object = JSON. No release, no deploy. { "module": "warranty_claim", "fields": [ … ], "form": { … }, "list": { … }, "validators": [ … ], "permissions": [ … ] } // Save → schema migration + FE renderer + validators, automatic, tenant-scoped
Because every capability is already a JSON document, the same substrate that lets a human author a definition lets an LLM author one. This is not a downstream feature; it is the foundational architectural decision. The marginal cost of a new capability trends toward the cost of writing a definition rather than deploying code.
Part I · Product surfaces →

What customers use

A CRM as the core product, with the sales-workflow layer on top. Every surface renders dynamically from definitions on a shared runtime.

CRM · Classic

Live · core product

Contacts, companies, deals, pipelines, tasks, notes and any number of custom modules, all as Module definitions. Forms, lists, detail views and validators render fully dynamically.

Email · Marketing + Mail Client

Live · bestseller

Campaigns (audience via Lead Search) and a full 1:1 mail client inside the CRM. Sending goes through the customer's own channel (SMTP / Google / Microsoft); reputation stays with their domain, no shared relay.

Calling & Call Intelligence

In progress

A Twilio dial-pad (WebRTC) & SMS already exist in the CRM. Being extended into a sales-call layer: pre-call briefing, in-call assistance, post-call summarisation, each on Agent & Flow definitions.

AI Chat / Assistant

Approaching launch

A global assistant layer spanning every CRM feature, embedded and standalone. Evolves from Q&A chat into a personal assistant: next-best actions, drafts, deal summaries, cross-feature flows.

Content Creation

Planned

Assistant for website copy, outbound content and chat scripts. Agent definitions with brand guardrails, review flows and per-channel publishing connectors.

Additional channels

Roadmap

SMS, WhatsApp, LinkedIn and further outreach channels on the same Agent + Flow substrate. The channel is new; the shape of the work is not.

Part II · §6 · The pattern repeats →

How we solve it: six subsystems, one pattern

The same definition/processor shape carries six very different subsystems. New subsystems inherit inspectability, versioning, AI-authorability and testability for free.

SubsystemDefinitionProcessor
CRM modulesFields · form · list · detail · validatorsreact-fe renderer + laravel-api schema/validator
Process flowsSteps · branches · tool / LLM / agent callsOrchestrator Engine
AI agentsPrompt · tools · memory · guardrailsOrchestrator Engine + AI API
MCP toolsName · input/output schema · side-effect scopeMCP Processor
Email campaignsAudience · template · schedule · deliverabilitylaravel-api campaign engine + SMTP
Lead searchSearch / crawl / enrichment definitionslead-search-engine
Part III · System architecture →

Nine services, cleanly bounded

Multi-tenant from row zero. Each service has an identity and (often more informative) a defined anti-scope. The Orchestrator is the centre every AI capability converges on.

laravel-apiPHP · Laravel

System of record. CRM data (MySQL), auth, tenant boundary, queues (Horizon), outbound integrations.

react-feTS · React

Multi-audience surface (customer/admin/support/dev). Renders dynamically from definitions. Hosts CRM, marketing, calling & the 5 authoring tools.

Future main processor

Executes every Flow & Agent definition. One runner, three entry paths: chat, in-CRM action, headless trigger.

ai-apiPython · FastAPI

The model gateway. Every LLM call, embedding and RAG retrieval crosses this boundary; provider swap = one place.

mcp-processorTS · Node

Hosts the MCP tool catalogue. Registered once → callable everywhere. Validates inputs/outputs, enforces side-effect scope.

chat-feNext.js → Vite

Real-time assistant surface, embedded & standalone. Consolidating onto the Orchestrator store (path to a stateless FE).

B2B retrieval & enrichment. Crawlers + 3rd-party → normalisation/dedup → Qdrant vector store (RAG-ready). Sellable as a standalone API.

zapierPrivate app

Outbound integration, live in production. Connects Wholix to thousands of apps via Zapier's catalogue. Marketplace listing = GTM switch.

infraTerraform

Infrastructure as code. AWS (CRM stack) + Hetzner (AI stack), DNS, TLS, environments, deploy scripts. No hidden cloud config.

Part III · §9 · High-level system map →

Data flow across the platform

The authoritative topology: every node and every dependency below has a running process and a working connection in production today. Requests flow top-to-bottom; every LLM call crosses the AI API, every CRM read/write crosses the Laravel API.

Clients & entry paths
User BrowserCustomer · admin · support · dev
React CRM FEfe.wholix.net → Laravel API
Chat FENext.js → Vite · streams to Orchestrator
Headless Triggerqueue · webhook · cron → Orchestrator
three entry paths converge on one runner
Core runtime
Laravel APIapi.wholix.net · system of record · multi-tenant boundary · Horizon queues
Orchestrator EngineFlow & Agent runner · calls AI API · MCP · Lead Search · writes back via Laravel API
AI-driven behaviour is dispatched to specialised services
AI · tools · retrieval
AI APIai.wholix.net · model gateway · embeddings · RAG
MCP ProcessorTool catalogue · calls back into Laravel API
Lead Search EngineCrawlers + enrichment → Qdrant
OpenAI / Anthropic / …External LLM providers · behind the gateway
persistence & the outbound integration surface
Data stores & integrations
MySQL · RDSCRM system of record
MongoDB ×2Orchestrator + chat state
QdrantVector DB · RAG substrate
RedisQueues (Horizon) · cache
S3Files · exports · assets
TwilioCalling / SMS
SMTPCustomer email sending
Horizon WorkersEmail sync · campaigns · enrichment jobs
Central runtime Service Data store External provider

Chat messages, in-CRM actions and headless triggers all resolve to one set of Flow definitions on the Orchestrator, through one observability layer. This mirrors the authoritative Mermaid topology in Part III · §9. See the repo for the exact arrowed diagram.

Part III · §11–13 · Data, tenancy & security →

Multi-tenancy as a primitive, not a filter

MySQL · RDS
System of record for all CRM entities. Isolation at the schema: every entity carries account_id.
MongoDB ×2
Orchestrator execution state (traces, sessions) + chat store (consolidating onto one store).
Qdrant
Vector store for embeddings, a RAG substrate with tenant-aware filters on every lookup.
Redis
Queue backend (Horizon), cache. Keys namespaced by account.
S3
Files, exports, assets. Bucket/prefix layout keyed by account, EU region.
  • At the schema: the persistence layer refuses cross-account writes.
  • At the API: every request resolves an account context first, so no path reads CRM data without a scope.
  • In the runtime: Orchestrator, AI API, MCP, Lead Search carry the account context through every internal call.
  • Customer sending never uses a shared relay; deliverability reputation stays with the customer.
  • Secrets never in git. Per-tenant secrets encrypted at rest, decrypted only at the boundary that uses them.
  • SOC 2 Type I preparation, SSO & an audit-log inventory are within the current planning horizon.
Part IV · The authoring platform →

The authoring tools are the product and the moat

Feature velocity is unbundled from release velocity. The extender pool grows over time: today engineers & senior CSMs → 2026 power users → 2027 AI-assisted → beyond, runtime adaptation.

Module Builder

Live internal

CRM objects as JSON → forms, lists, detail, validators, permissions. Saving migrates the schema & deploys renderers automatically.

Flow Studio

Live internal

Visual authoring of Process Flows (branches, tool / LLM / agent calls). Output = a Flow definition for the Orchestrator. Every run produces traces.

Agent Builder

Live internal

Declarative agents (prompt + tools + memory + guardrails + model policy) as JSON, versioned, tested, composable inside Flows.

MCP Tool Catalogue

Live internal

Register a capability once → instantly callable from every Agent & Flow, including existing ones. Single source of truth for "what can this platform do".

+ Process Builder

Live · daily production

An older but still-used surface for CRM-centric automations (LLM agents + CRM data operations), executed as Laravel Horizon workers. Bidirectionally composable with Flow Studio: a Process can invoke a Flow and vice versa.

Every improvement to an authoring surface is a permanent multiplier on every future feature: a new MCP tool becomes callable from every existing & future Agent and Flow; a new Flow node applies to every Flow, retroactively. That is the compounding curve, not a marketing claim.
Part V · Delivery & CI/CD →

Six-stage pipeline: fast and safe

Cheap checks early, deliberate decisions late. Every PR gets an ephemeral live environment (FE + API) with isolated fixture data. AI accelerates the input; the pipeline enforces the same standard regardless of how the code was authored.

01
Local
Run & test locally, validate against definition schemas.
Auto
02
Branch Remote
Push → ephemeral live environment on the branch.
Auto
03
Pull Request
Review by a 2nd engineer + CI (lint, type, unit, integration).
Auto + review
04
CI/CD Merge
Merge to main → auto-deploy to staging.
Auto
05
Remote QA
End-to-end verification on staging.
Human
06
Prod
Deliberate, logged, reversible deploy by hand.
Deliberately manual
Part VI · Scaling model →

Three independent scaling vectors

Each addressable without touching the others. Per the deep-dive, 10× and 100× are operational changes, not an architectural rewrite. The third vector is the one that returns capital on a different curve.

Vector 1
Infrastructure scale

Stateless services, queue-backed workers, horizontally ready. Adding capacity = a Terraform change, not an architecture change.

Cost curve: linear · understood
Vector 2
Tenant scale

Account-isolated schema & hot paths. New tenants do not degrade existing ones, with no shared points of contention.

Cost curve: linear · understood
Vector 3 · the compounding one
Authoring scaleWhere the return concentrates

Every new capability delivered through the authoring tools multiplies what an engineer (and soon a power user, then an AI) can ship without touching code.

Cost curve: sub-linear · compounds