-
Notifications
You must be signed in to change notification settings - Fork 12
Architecture and Order Flow
tien.nguyen edited this page Jul 30, 2026
·
1 revision
This document describes the architectural layout, service boundaries, database ownership, communication protocols, and end-to-end order execution lifecycle of the Emporia Trading Platform.
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
| 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) |
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
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.
- Trading Terminology Glossary
- Order Lifecycle & Validation
- Order Routing & SOR
- Market Data & Pricing
- Portfolio & Risk Management
- Architecture & Order Flow
- Static Data Service
- Market Data Service
- Order Command Service
- Order Management Service (OMS)
- Execution Service
- Portfolio Service
- Design Patterns
- Microservices Overview
- Exchange-Core Integration
- Testing & Verification
- Deployment & Operations
- Repository: emporia
- Tech Stack: Java 21 | Spring Boot 4.0.7 | React 19 | Kafka | gRPC
- Coverage: 91.95% JaCoCo