Skip to content

01 — System Architecture

As of 2026-05-28.

TL;DR

QuantaTrade's platform is a Node.js / TypeScript monorepo (QuantaTradeAI/platform) of small services around a separate Java matching engine (QuantaTradeAI/exchange-core, a fork of exchange-core2). The platform speaks gRPC to the engine, NATS pub/sub + request-reply between services, and REST + WebSocket to clients. The admin surface (QuantaTradeAI/admin-panel, Next.js 14) talks Connect-protocol gRPC-web to the engine's AdminService.

The runtime authority for balances is the matching engine's in-memory UserRegistry. PostgreSQL accounts + ledger_entries is the auditable mirror maintained by ledger-service. Drift between the two is a real risk and is actively guarded against by deposit-sync wiring landed 2026-05-27 (see 03-ledger-accounting.md).

High-level shape

%%{init: {'theme':'base','themeVariables':{'background':'#ffffff','primaryColor':'#ddf4ff','primaryBorderColor':'#0969da','primaryTextColor':'#0a0a0a','lineColor':'#1f2328','secondaryColor':'#fff8c5','tertiaryColor':'#dafbe1','clusterBkg':'#f6f8fa','clusterBorder':'#d0d7de'}}}%%
graph LR
    subgraph Clients
        TRADE[trading-ui<br/>Next.js]
        ADMIN[admin-panel<br/>Next.js]
    end

    subgraph Edge["Edge / API"]
        APIGW[api-gateway<br/>NestJS]
        WSGW[ws-gateway<br/>WebSocket]
    end

    subgraph Platform["Platform services (TS)"]
        OR[order-router]
        LED[ledger-service]
        PMS[pms-service]
        RISK[risk-service]
        SUB[subscription-service]
        VBIN["venue-adapter-binance<br/>(PR#6, in-flight)"]
    end

    subgraph Engine["Matching"]
        ME[exchange-core<br/>Java + exchange-core2]
    end

    subgraph Data
        PG[(PostgreSQL<br/>Prisma)]
        REDIS[(Redis)]
        NATS[NATS]
    end

    TRADE --> APIGW
    TRADE -.WS.-> WSGW
    ADMIN -.gRPC-web.-> ME

    APIGW --> OR
    APIGW --> LED
    APIGW --> PMS
    APIGW --> SUB

    OR -.gRPC.-> ME
    OR -.NATS.-> LED
    OR -.NATS.-> WSGW
    OR -.NATS.-> PMS

    ME -.NATS trades.-> LED
    ME -.NATS trades.-> WSGW
    ME -.NATS trades.-> PMS

    VBIN -.NATS venue trades.-> OR

    LED --> PG
    PMS --> PG
    APIGW --> PG
    SUB --> PG
    OR --> REDIS

    style Engine fill:#ddf4ff
    style Platform fill:#ddf4ff
    style Edge fill:#ddf4ff
    style Data fill:#f6f8fa

Repository layout

Repo Tech What lives here
QuantaTradeAI/platform Node.js 20, TypeScript, NestJS (api-gateway), npm workspaces, Prisma All 8 TS services + 7 shared packages
QuantaTradeAI/admin-panel Next.js 14, React 18, Connect-protocol Operator console
QuantaTradeAI/exchange-core Java 17, Spring Boot, exchange-core2 Matching engine + AdminService gRPC
QuantaTradeAI/trading-ui Next.js 15 End-user trading UI
QuantaTradeAI/contracts Solidity, Hardhat Token, sale, vesting, staking, revenue router (M2/M5)
QuantaTradeAI/docs Markdown This document, milestone status, specs

This reference doc set covers platform + admin-panel; the other repos are referenced where they intersect.

Services in platform/services/

Service LOC (TS) Port Role
api-gateway ~12k 3001 (REST) NestJS app: auth, accounts, orders, custody, fees, audit. Most user-facing logic.
order-router ~2.7k 3003 / 50051 (gRPC) Validates orders, runs the risk-checker, routes to matching-engine, mirrors trades.
ledger-service ~1k 3007 Double-entry ledger writer. NATS RPC ledger.credit/debit/lock/unlock/settleTrade.
pms-service ~3k 3008 Position & PnL tracking (spot now; margin in M8).
risk-service ~1.5k 3009 Margin & liquidation engine (M8 derivatives prep). Distinct from order-router's pre-trade risk-checker — see 04-risk-controls.md.
subscription-service ~0.6k 3011 Subscription tiers (3 tiers, USDC/QTRA payments).
ws-gateway ~1.4k 3002 (WS) Authenticated WS fan-out for trade events, order updates, depth feeds.
venue-adapter-binance 🟡 ~0.8k 3010 [PR#6] Read-only Binance market data → NATS.

Shared packages in platform/packages/

Package Role
@quantatrade/common Decimal arithmetic, idempotent retry, auth/JWT, audit helpers, validation. The arithmetic primitives (add, subtract, multiply, isLessThan, isPositive) are used by every service that touches balances.
@quantatrade/db Prisma client + schema.prisma (24 models, 693 lines).
@quantatrade/logger ContextLogger interface. Recent fix added logError(msg, err, meta) and logTrade(meta) — see PR#2 history.
@quantatrade/metrics Prometheus client wrapper.
@quantatrade/nats NATS pub/sub + request-reply wrapper.
@quantatrade/temporal Temporal workflow client (used by ledger-service for backups + activity reconciliation).
@quantatrade/types Shared TS types (Order, Trade, LedgerEntry, KycStatus, CustodyTransaction, etc.). 24 models worth of interfaces.

Transport choices

From → To Protocol Why
Client → api-gateway REST + JWT Public-API convention; idempotency via header.
Client → ws-gateway WebSocket + JWT Authenticated streams: orders, trades, depth.
Admin UI → exchange-core gRPC-web (Connect protocol) Direct to the engine for operator commands (ListOrders, CancelOrderAdmin, etc.). The admin panel does not go through the platform services for engine commands.
api-gateway → other services NATS RPC + REST Internal call shapes; idempotency via transactionId for ledger writes.
order-router → exchange-core gRPC Order placement, cancellation, market-discovery.
exchange-core → platform NATS pub/sub Trade events, deposit confirmations, order-state changes.
venue-adapter-binance → order-router NATS (venue.*.trade.*) Reference prices for the risk-checker [PR#6].

Authority and trust boundaries

%%{init: {'theme':'base','themeVariables':{'background':'#ffffff','primaryColor':'#ddf4ff','primaryBorderColor':'#0969da','primaryTextColor':'#0a0a0a','lineColor':'#1f2328','secondaryColor':'#fff8c5','tertiaryColor':'#dafbe1','clusterBkg':'#f6f8fa','clusterBorder':'#d0d7de'}}}%%
graph TB
    subgraph Trusted["Trusted: runs in the same VPC"]
        APIGW[api-gateway]
        OR[order-router]
        LED[ledger-service]
        ME[exchange-core engine]
        ADMIN[admin-panel]
    end

    subgraph Authority["Authoritative state"]
        UREG["UserRegistry<br/>in-memory in exchange-core"]
        PG_LEDGER[(ledger_entries<br/>auditable mirror)]
    end

    subgraph External["External / less-trusted"]
        BITGO[BitGo custody]
        BINANCE[Binance market data]
        SUMSUB[Sumsub KYC]
    end

    OR -- "places & cancels" --> UREG
    ME -- "settle event" --> LED
    LED -- "writes" --> PG_LEDGER
    BITGO -- "webhook deposit.confirmed" --> APIGW
    APIGW -- "deposit RPC" --> ME
    APIGW -- "ledger.credit" --> LED
    BINANCE -- "L2 + trades<br/>(read-only)" --> OR
    SUMSUB -. KYC webhook .-> APIGW

    classDef authority fill:#ddf4ff,stroke:#e65100,stroke-width:2px
    class UREG,PG_LEDGER authority

Single rule that governs everything: the engine is the runtime source of truth. The ledger is an auditable mirror, not a back-pressure. A ledger write that fails does not roll back an engine state change (it's logged and alertable instead). See 03-ledger-accounting.md for the consequences and the eventual reconciliation strategy.

Deployment topology

Production / staging (these are the same EC2 instance today): - 1× EC2 t3.2xlarge at 34.199.105.99 - Cloudflare DNS (DNS-only, not proxying) → nginx → docker-compose services - 7 subdomains under quanta.emoment.tech: api, ws, admin, matching, trade, presale, investor - Let's Encrypt certs, auto-renewed via certbot - SSH key: ~/.ssh/quantatrade-key.pem

The split into multi-environment (separate UAT + prod) is planned but not yet executed; see 09-deployment-and-ops.md for the current single-host shape.

Cross-cutting concerns

Concern Where it lives See
Authentication api-gateway/src/auth/, JWT signed with HS256 from env, refresh via Redis 05-services-reference.md
Authorisation / RBAC Currently coarse — admin vs user. Operator-tier RBAC is M4 scope. 06-admin-panel.md
Idempotency ledger_entries.transactionId UNIQUE, IdempotencyKey table at api-gateway boundary 03-ledger-accounting.md
Audit logging AuditLog Prisma model, written from api-gateway middleware on every state-changing call 07-data-model.md
Rate limiting NestJS throttler on api-gateway routes; nginx-level for public endpoints 09-deployment-and-ops.md
Secrets .env per host, never copied between hosts. Sensitive env vars listed per service. 09-deployment-and-ops.md

Where the architecture diverges from the original plan

docs/architecture.md (original delivery-plan diagram) shows several services that do not yet exist as code:

Planned Code today Plan vs reality
Strategy Engine (Python) not built M4 deliverable
Signal Engine (AI predictions) not built M7
Sentiment Engine (news/social) not built M6
Custody Service minimal scaffold M2 deliverable; production custody calls go through api-gateway today
Treasury Service not built M5 (revenue router)
KYC Service not built (api-gateway has KYC tables only) M4
AML Monitor not built M4
Chain Indexer not built M2
Token, Sale, Vesting, Staking contracts not built M2 / M5

This reference doc set documents what's built. See 10-planned-modules.md for what's specified-but-not-coded and the path to it.