Architecture
FixPortal separates the public and operator UI, the simulator backend, and content authoring so each can ship on its own cadence without sharing a database or source tree.
Runtime path
The React application is a Vite-built SPA with prerendered public routes. Authenticated commands and queries use REST; live session, order, and traffic updates use SignalR. React Query owns server state, Zustand owns small client preferences, and MSAL supplies Entra authentication in cloud builds.
The .NET 10 backend is an ASP.NET Core minimal API and SignalR host. It owns tenant authorization, SQL Server persistence, simulation policy, and operational endpoints. Its engine and simulation projects wrap QuickFIX/n sessions and turn policy into FIX messages.
The SQL-free Acceptor.Lite project supports the demo venue. Its public demo contract is separate from the operator REST contract.
Repository boundaries
- fixportal-simulator-frontend owns the SPA, public pages, docs/blog MDX, generated REST type declarations, and committed consumer contract snapshots.
- fixportal-simulator-backend owns REST, SignalR, DTO, ATDL, persistence, and FIX-runtime contracts.
- fixportal-cms is a Keystatic editor over this repository's
content/directory; it owns no content database. - fixportal-engine remains a separate reusable FIX-engine product. Do not assume every simulator runtime concern belongs there.
Contracts
The backend publishes OpenAPI, SignalR, TypeScript-shape, and ATDL state-rule snapshots. The frontend commits consumer snapshots under contracts/. npm run generate:rest-types writes REST type declarations to src/api/generated/; it does not generate an HTTP client. Hand-maintained application types in src/api/types.ts form the stable facade consumed by UI code.
The backend's parity tests compare its DTOs with the frontend snapshot, preventing one repository from silently renaming or removing fields.
Content and deployment
Docs and blog entries are MDX compiled into the released frontend. A content change therefore goes through frontend build and prerender checks. The content workflow composes current content with an already released application version, then publishes the resulting static site. Merging an edit does not mutate a live database.
Theme persistence
The published site theme lives in one PlatformSettings row keyed theme_overrides, holding a JSON blob. Saved theme presets live in their own ThemePresets table. Only an unpublished draft touches the browser: it sits in localStorage and is merged over the fetched published theme on boot. White-label snapshot builds skip the runtime fetch and bake the published theme into the static build instead.
Security boundaries
Tenant identity is enforced by the backend, not trusted from browser state. Customer builds are generated from the same source with site-specific assets and exclusions. Brand-leak tests, auth gates, and server authorization are separate controls; none substitutes for another.
Updated 2026-09-10 · Edit on GitHub