Skip to content

Architecture and Order Flow

tien.nguyen edited this page Jul 30, 2026 · 1 revision

System Architecture & Order Flow

This document describes the architectural layout, service boundaries, database ownership, communication protocols, and end-to-end order execution lifecycle of the Emporia Trading Platform.


๐Ÿ›๏ธ Architectural Overview

Emporia employs a hybrid architecture combining Synchronous REST/gRPC API Gateway Routing for client interactions with an Asynchronous Event-Driven Architecture (EDA) powered by Apache Kafka for order command processing and execution routing.

flowchart TD
    subgraph Frontend ["Frontend Layer"]
        UI["React 19 Trading Dashboard :3001"]
    end

    subgraph GatewayLayer ["Gateway & Security Layer"]
        GW["Spring Cloud Gateway :8082"]
        AUTH["OAuth2 Authorisation Server :9000"]
    end

    subgraph DomainServices ["Domain Microservices"]
        STATIC["Static Data Service :8081"]
        PREF["User Preferences Service :8083"]
        MARKET["Market Data Service :8084 / :50551"]
        CMD["Order Command Service :8085"]
        OMS["Order Management Service :8086"]
        EXEC["Execution Service :8087"]
        PORT["Portfolio Service :8088"]
    end

    subgraph EventBroker ["Kafka Event Bus"]
        K1[["emporia.order.commands.v1"]]
        K2[["emporia.order.results.v1"]]
        K3[["emporia.orders.v1"]]
        K4[["emporia.execution.commands.v1"]]
    end

    UI -->|REST / SSE / WebSocket| GW
    GW --> AUTH
    GW --> STATIC
    GW --> PREF
    GW --> MARKET
    GW --> CMD
    GW --> OMS

    CMD -->|Produce Order Command| K1
    K1 -->|Consume Command| OMS
    OMS -->|Produce Correlation Result| K2
    K2 -->|Consume Result| CMD
    OMS -->|Produce Immutable Order Event| K3
    K3 -->|Consume Order Event| EXEC
    EXEC -->|Produce Execution Command| K4
    K4 -->|Consume Execution Command| OMS
Loading

๐Ÿ”Œ Microservice Ports & Capabilities

Service Port(s) Business Capability Storage Boundary
authorisation-service 9000 OAuth2 / OIDC server, token issuance, user authentication emporia_authorisation (PostgreSQL)
static-data-service 8081 Exchange listings, instrument definitions, symbol lookups emporia_static_data (PostgreSQL)
gateway 8082 Unified API entrypoint, CORS, route mapping Stateless
user-preferences-service 8083 User watchlists, UI workspace layouts, preferences emporia_client_config (PostgreSQL)
market-data-service 8084 (HTTP) / 50551 (gRPC) Market quotes, order book aggregation, SSE & gRPC streams In-memory cache / external feeds
order-command-service 8085 Command intake, client validation, command correlation Stateless (In-memory correlation store)
order-management-service 8086 State machine persistence, lifecycle tracking, fill processing emporia_order_data (PostgreSQL)
execution-service 8087 Order routing strategy (SMART/VWAP), exchange-core adapter Stateless
portfolio-service 8088 Position tracking, P&L calculations, risk snapshots emporia_portfolio (PostgreSQL)

๐Ÿ”„ End-to-End Order Lifecycle Flow

sequenceDiagram
    autonumber
    actor Client as Trader / React UI
    participant Gateway as API Gateway (:8082)
    participant CmdService as Order Command Service (:8085)
    participant KafkaCmds as Kafka (order.commands.v1)
    participant OMS as Order Management Service (:8086)
    participant DB as PostgreSQL (emporia_order_data)
    participant KafkaOrderLog as Kafka (orders.v1)
    participant ExecService as Execution Service (:8087)
    participant KafkaExecCmds as Kafka (execution.commands.v1)

    Client->>Gateway: POST /api/orders (OrderCommand)
    Gateway->>CmdService: Forward Request
    CmdService->>CmdService: Validate symbol against Static Data Service
    CmdService->>KafkaCmds: Publish CREATE Command (CommandId)
    CmdService-->>Client: 202 Accepted (CommandId & Correlation Token)

    KafkaCmds->>OMS: Consume CREATE Command
    OMS->>DB: Persist TradingOrder (Status: PENDING_NEW -> LIVE)
    OMS->>KafkaOrderLog: Publish OrderCreated Event
    OMS->>KafkaCmds: Publish Correlation Success to order.results.v1

    KafkaOrderLog->>ExecService: Consume OrderCreated Event
    ExecService->>ExecService: Determine Routing (SMART / Exchange-Core)
    ExecService->>KafkaExecCmds: Publish Fill/Execution Command

    KafkaExecCmds->>OMS: Consume Execution Command (Apply Fill)
    OMS->>DB: Update TradingOrder (TradedQty, RemainingQty, Status: FILLED/PARTIAL)
    OMS->>KafkaOrderLog: Publish OrderFilled Event
Loading

๐Ÿ›ก๏ธ Database-per-Service Isolation Principle

Emporia strictly enforces Database-per-Service:

  • No service can directly query or write to another service's database.
  • Cross-domain data requirements (e.g., validating a ticker symbol before order placement) are resolved asynchronously via Kafka events or synchronously via internal HTTP client calls (RestClient).
  • Database schema changes in one service have zero cascade impact on other domain services.

Clone this wiki locally