Component architecture

Table of Contents

This is the ground-truth reference for ORE Studio's component directory layout. All tooling (codegen output paths, compass scaffolds, CI) must agree with this document. If a discrepancy is found, fix the tooling — not this document.

Return to Knowledge.

Two component meta-models

ORE Studio uses exactly two component layouts. Choose based on whether the component needs an API/implementation split.

Simple component

A single CMakeLists.txt at the root; include/, src/, tests/, and modeling/ directly inside. No sub-component split. Named ores.<name>. When writing about architecture, say simple component rather than "component without sub-components".

Use when: the component is an infrastructure library, a tool, or a shared utility with no need to separate public API from DB/service concerns.

projects/ores.database/
├── CMakeLists.txt
├── include/ores.database/
├── src/
├── tests/
└── modeling/

Current simple components:

Component Role
ores.cli CLI argument parsing and command dispatch
ores.connections Connection pool abstraction
ores.database Database access layer (sqlgen, migrations)
ores.diff Structural diff utilities
ores.fpml FpML parsing library
ores.geo Geographic utilities (IP-to-country, etc.)
ores.logging Boost.Log setup and logger factory
ores.nats NATS client wrapper
ores.platform Platform abstraction (reflect-cpp, JSON glue)
ores.security Authentication and authorisation primitives
ores.service Shared service-layer helpers (handler_helpers, request_context)
ores.shell Interactive shell and command registry
ores.storage Object storage client
ores.testing Test helpers and fixtures
ores.utility General-purpose utilities (UUID, time, string)
ores.wt.service Wt web framework service host

Composite component

A parent directory projects/ores.<group>/ contains child sub-component directories (short names: api, core, service, …). Each child is an independent CMake target. The parent directory holds no CMakeLists.txt of its own (decision D5, sprint 19 PR #997). When writing about architecture, say composite component rather than "component with sub-components" or "component group".

Sub-component names follow the conventions in Sub-component catalogue. Child CMake targets keep the fully-qualified name: ores.<group>.api, ores.<group>.core, etc.

projects/ores.refdata/
├── api/
│   ├── CMakeLists.txt
│   ├── include/ores.refdata.api/
│   ├── src/
│   ├── tests/
│   └── modeling/
├── core/
│   ├── CMakeLists.txt
│   ├── include/ores.refdata.core/
│   ├── src/
│   ├── tests/
│   └── modeling/
├── service/
│   └── …
└── modeling/          ← group-level codegen entity models

Use when: the component owns domain types used by other components (api), DB repositories (core), and/or a runnable message-handler host (service).

Current composite components and their active sub-components:

Group Sub-components
ores.analytics api, core, service, modeling
ores.assets api, core, service
ores.compute api, core, service, wrapper, modeling
ores.controller api, core, service, modeling
ores.dq api, core, service, modeling
ores.eventing api, core, modeling
ores.http api, core, server
ores.iam api, core, service, client, modeling
ores.marketdata api, core, service
ores.ore api, core, service
ores.qt application, api, refdata, analytics, compute, data_transfer, mktdata, party, scheduler, trading, workflow, workspace, admin
ores.refdata api, core, service, modeling
ores.reporting api, core, service, modeling
ores.scheduler api, core, service, modeling
ores.synthetic api, core, service
ores.telemetry core, service, database
ores.trading api, core, service, modeling
ores.variability api, core, service
ores.workflow api, core, service, modeling
ores.workspace api, core, service, modeling

Stale top-level directories (decommissioned in sprint 19, not yet deleted): projects/ores.refdata.api/, projects/ores.refdata.core/, projects/ores.trading.api/, projects/ores.trading.core/. These receive wrong codegen output and must be ignored. See Known issues.

Sub-component catalogue

Exhaustive list of every sub-component name in use and its canonical role.

Standard roles (most groups use these three)

Name Full name Role
api ores.<group>.api Public domain types (POCOs), JSON I/O, table I/O, generators, NATS protocol structs, eventing event types. No DB or service deps. Consumed by all other sub-components and by external consumers.
core ores.<group>.core Repositories (sqlgen entities, mappers, CRUD), business-logic service layer, DB access. Depends on api. Not runnable.
service ores.<group>.service Runnable host: NATS message handlers, startup wiring, main entry point. Depends on core.

Specialist roles

Name Used in Role
server ores.http HTTP/web server entrypoint — wires HTTP routes and runs the Boost.Asio event loop. Equivalent to service but for HTTP rather than NATS.
client ores.iam Client-side library — session management and authentication helpers for Qt and service consumers. Provides the consumer-facing API without coupling consumers to core internals.
wrapper ores.compute External process wrapper/bridge — executes ORE risk runs as a child process and reports results back to core.
database ores.telemetry Database persistence layer — owns the DB schema and repository for the group when the persistence concern is large enough to separate from core.

Application-layer roles (ores.qt only)

ores.qt is the Application layer: a single composite component whose children are Qt UI plugins, each projecting one domain area. The sub-component names here are domain-area names, not the standard roles.

Name Role
application The Qt MDI host application — main window, MDI area, plugin loader, menu bar.
api Shared Qt types and utilities used across all Qt plugins.
refdata Reference-data Qt plugin (country, currency, rounding types, …).
analytics Analytics Qt plugin.
compute Compute Qt plugin.
data_transfer Data-transfer Qt plugin.
mktdata Market-data Qt plugin.
party Party-management Qt plugin.
scheduler Scheduler Qt plugin.
trading Trading Qt plugin.
workflow Workflow Qt plugin.
workspace Workspace Qt plugin.
admin Administration Qt plugin.

Modeling directory (not a CMake target)

Name Role
modeling Codegen entity org models and component documentation (component_overview.org, PlantUML diagrams). Not a compilable target; used only by codegen and documentation tools. May appear at the group level (projects/ores.refdata/modeling/) or as a child of a simple component or sub-component.

Facet placement

Code is organised into facets within include/ and src/. Each facet belongs in exactly one sub-component:

Facet api core service Description
domain     Domain types (POCOs), JSON I/O, table I/O
generators     Test-data generators
messaging   NATS protocol structs in api; handler class in core
eventing     Event types
repository     sqlgen entities, mappers, repositories
service     Business-logic service layer
app     Executable hosting and startup
config     CLI parser and options struct

CMake dependency chain

Typical target_link_libraries per part (generated by scaffold profiles; adjust to actual deps after generation):

Part PUBLIC PRIVATE
api ores.eventing.lib, ores.platform.lib ores.utility.lib, faker-cxx, libfort
core ores.<group>.api.lib, ores.nats.lib ores.service.lib, ores.platform.lib, ores.utility.lib, ores.security.lib, faker-cxx, libfort
service ores.service.lib, ores.security.lib, ores.<group>.core.lib, ores.eventing.lib, ores.nats.lib, ores.database.lib, ores.utility.lib, ores.telemetry.lib

CMake visibility rules:

  • PUBLIC: headers exposed in the component's own public API; consumers also see (and link) the dependency.
  • PRIVATE: used only in .cpp files; consumers do not inherit it.
  • INTERFACE: expose to consumers without linking directly (avoids duplicate-library warnings on macOS).

Common transitive deps — do not add explicitly:

  • reflectcpp arrives transitively via ores.platform.lib (PUBLIC)
  • Boost::program_options arrives via ores.telemetry.lib (PUBLIC)

Scaffold profiles

Codegen (--profile <name>) generates all boilerplate for each part. See ORE Studio Codegen §"Profile catalogue" for the template list.

Profile Part Files generated
component-api api CMakeLists (root, src, tests, modeling), component header, stub header+impl, test main+stub
component-core core same set with core-flavoured CMake deps
component-service service same core set + app/config headers+impls + main.cpp

After generation, register each part in projects/CMakeLists.txt in dependency order (apicoreservice). Each part also needs a .puml diagram stub in modeling/ — not yet generated by codegen, so add it manually.

Known issues

Issue Status
Stale top-level directories ores.refdata.api/, ores.refdata.core/, ores.trading.api/, ores.trading.core/ — decommissioned in sprint 19 but not yet deleted. Codegen currently writes to these stale paths instead of ores.refdata/api/ etc. Open — tracked in Refactor ores.codegen C++ generation
Facet catalogue uses projects/ores.{component_include}/ and projects/ores.{component_core}/ as output roots. Should be projects/ores.{component}/api/ and projects/ores.{component}/core/. Open — same story

See also

Emacs 29.1 (Org mode 9.6.6)