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.cppfiles; 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:
reflectcpparrives transitively viaores.platform.lib(PUBLIC)Boost::program_optionsarrives viaores.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 (api → core → service). 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
- ORE Studio Codegen — profile catalogue and codegen usage.
- component-creator — skill for scaffolding a new component.
- component-model-creator — skill for writing the architecture docs.
- Component Documentation Guide — how to fill in each section of
component_overview.org. - Regroup C++ components — sprint 19 story that established the grouped layout.