How rahul-mygit/cex-v2-boilercode works
1. Top-level shape
- This repo is split into two independently run Bun/TypeScript services:
- backend/: the HTTP API and auth layer
- engine/: the exchange worker that owns matching/state
- They communicate only through Redis queues; there is no direct backend-to-engine function call.
2. Backend as the synchronous API boundary
- backend/src/index.ts boots an Express server on port 3000, wires routes, and also starts a Redis consumer for engine replies.
- The backend does not match orders itself. It accepts HTTP requests, validates them, forwards commands to Redis, waits for a correlated response, and then returns JSON to the caller.
3. Backend request flow
- HTTP routes live under backend/src/routes/, with controller logic in backend/src/controllers/.
- Exchange endpoints are effectively a request/response proxy over Redis:
- route handler -> validation -> engine client -> pending response tracking -> engine reply -> HTTP response
- backend/src/store/pending-responses.ts is the in-memory map that holds outstanding requests by correlationId until the engine replies or times out.
4. Backend authentication and database
- User identity is persisted in Postgres via Prisma (backend/prisma/schema.prisma, migrations in backend/prisma/migrations/).
- backend/src/db.ts initializes the Prisma client.
- backend/src/utils/auth.ts handles JWT creation/verification, and backend/src/utils/validation.ts + Zod schemas in backend/src/types/ validate request bodies.
- POST /signup is DB-backed; POST /signin is the auth gap called out in the README.
5. Backend-to-engine messaging contract
- backend/src/utils/engine-client.ts constructs Redis messages with:
- correlationId
- responseQueue
- type
- payload
- The backend publishes to the shared broker queue backend-to-engine-broker, then listens on a per-process queue named like response-queue-<BACKEND_QUEUE_ID>.
- This makes the backend horizontally scalable without shared in-memory response state across processes.
6. Engine as the stateful matching boundary
- engine/src/index.ts runs as a worker process that listens forever on the broker queue.
- It parses each backend message, routes it to the exchange logic, and replies to message.responseQueue with the same correlationId.
- The engine is the only place where order matching and exchange state live.
7. Engine state model
- engine/src/store/exchange-store.ts is the core state holder.
- The README indicates in-memory collections for:
- balances
- order books
- orders
- fills
- This means the engine is volatile by design: restarting it resets exchange state, while user records remain in Postgres.
8. Engine responsibilities and data semantics
- The engine is expected to implement:
- create_order
- get_depth
- get_user_balance
- get_order
- cancel_order
- Matching rules include limit-order crossing, optional market orders, partial fills, resting orders, and price-time priority.
- get_depth returns aggregated book levels by symbol; get_user_balance reads engine memory, not the database.
9. Important architectural boundary: durable vs volatile data
- Postgres/Prisma is used for durable user identity and auth data.
- Redis is used as the transport for cross-process coordination and reply routing.
- The engine’s order book, fills, and balances are ephemeral in-memory state, which is a deliberate architectural choice for this assignment.
10. Type and schema layer
- Both services use TypeScript types under backend/src/types/ and engine-side types/utils under engine/src/.
- Zod schemas define request validation on the backend before any DB write or queue publish happens.
- This keeps the HTTP surface strict while the engine can treat Redis payloads as command messages.
11. Operational/runtime details
- Both services run on Bun, use TypeScript, and rely on environment variables from their respective .env files.
- The backend additionally needs Postgres and Redis; the engine only needs Redis for transport.
- The repository includes separate README files plus flow-check docs, indicating the two processes are intended to be run independently during local development and evaluation.
12. What a diagram should emphasize
- Draw three major zones:
- client/API caller
- backend API + Postgres
- Redis broker + engine worker
- Show the backend as a stateless request coordinator except for the pending-response map.
- Show the engine as the exclusive owner of exchange state and matching logic.
Main entry points: auth-controller.ts Auth controller · index.ts Backend boot · exchange-controller.ts Exchange controller · engine-client.ts Engine client
Components 16
Client/API caller
External HTTP callers that interact with the backend API.
- API caller · HTTP consumers of the backend API.
Backend API
Stateless HTTP boundary plus auth, validation, and durable user storage.
- Backend boot · Starts Express, routes, and Redis reply consumer.
backend/src/index.ts - Auth routes · Signup/signin endpoints.
backend/src/routes/auth-routes.ts - Exchange routes · Order and market-data endpoints.
backend/src/routes/exchange-routes.ts - Auth controller · Handles authentication request flow.
backend/src/controllers/auth-controller.ts - Exchange controller · Validates exchange requests and coordinates Redis round-trips.
backend/src/controllers/exchange-controller.ts - Validation · Request-body validation before DB or queue writes.
backend/src/utils/validation.ts - JWT auth · JWT creation and verification helpers.
backend/src/utils/auth.ts - Prisma DB · Durable user identity storage via Prisma/Postgres.
backend/src/db.ts - Pending replies · Tracks outstanding Redis requests by correlationId.
backend/src/store/pending-responses.ts - Engine client · Builds correlated Redis command messages.
backend/src/utils/engine-client.ts - Auth schema · Zod schemas for auth payloads.
backend/src/types/auth-schema.ts - Exchange schema · Zod schemas for exchange payloads.
backend/src/types/exchange-schema.ts
Redis + Engine
Message broker and stateful matching worker.
- Redis broker · Shared queue transport between backend and engine.
- Engine worker · Consumes backend commands and sends correlated replies.
engine/src/index.ts - Exchange store · Owns balances, order books, orders, and fills in memory.
engine/src/store/exchange-store.ts
Connections 19
- API caller → Backend boot: HTTP requests · Clients call the backend API.
- Backend boot → Auth routes: mounts · Boot process wires auth routes.
- Backend boot → Exchange routes: mounts · Boot process wires exchange routes.
- Auth routes → Auth controller: dispatch · Auth routes invoke controller logic.
- Exchange routes → Exchange controller: dispatch · Exchange routes invoke controller logic.
- Auth controller → Validation: validates · Auth payloads are validated before use.
- Auth controller → Auth schema: uses · Auth controller relies on auth schemas.
- Auth controller → JWT auth: signs/verifies · JWT flow is handled in utilities.
- Auth controller → Prisma DB: reads/writes · Signup persists users in Postgres via Prisma.
- Exchange controller → Validation: validates · Exchange payloads are validated first.
- Exchange controller → Exchange schema: uses · Exchange controller relies on exchange schemas.
- Exchange controller → Engine client: publishes · Commands are forwarded to Redis with correlation metadata.
- Engine client → Pending replies: tracks · Outbound requests are registered for later replies.
- Backend boot → Pending replies: listens · Backend consumes reply messages and resolves pending requests.
- Engine client → Redis broker: send · Backend publishes commands to the broker queue.
- Redis broker → Engine worker: consume · Engine worker reads backend command messages.
- Engine worker → Exchange store: mutates/reads · Matching and query operations use in-memory exchange state.
- Engine worker → Redis broker: reply · Engine publishes correlated responses back to the response queue.
- Pending replies → Backend boot: resolve · Matched replies complete the HTTP request lifecycle.