Story: Regroup C++ components under product-group parent directories

Table of Contents

This page documents a story in Sprint 19. It captures the goal, current status, acceptance criteria, and the tasks that compose it.

Goal

Each product group (refdata, trading, iam, dq, analytics, reporting, scheduler, workflow, controller, database, workspace, compute) owns a single parent directory under projects/, with its sub-components (api, core, service, the qt UI) as children of that parent, plus a modeling/ directory that holds the group's codegen entity models.

Today the layout is flat:

,projects/
,├── ores.refdata.api/
,├── ores.refdata.core/
,├── ores.refdata.service/
,├── ores.qt.refdata/
,└── ores.refdata/modeling/      ← orphaned; added by the org-mode pilot

The target layout groups by product (decisions D1–D3 resolved the open choices — short child names, Qt under ores.qt/, no group-root CMakeLists):

,projects/
,├── ores.refdata/          ← domain group
,│   ├── api/
,│   ├── core/
,│   ├── service/
,│   └── modeling/          ← group models (separate story)
,└── ores.qt/               ← Application-layer group
,    ├── application/       ← the MDI host app
,    ├── api/
,    ├── refdata/           ← refdata Qt plugin
,    ├── party/
,    └── …                  ← every other Qt plugin

This makes the codegen "models belong to the group" property literally true on disk and makes IDE navigation match the conceptual layout. The Qt plugins group under ores.qt/ because they are the Application layer projecting the Domain layer — a separate architectural band from the domain group they present (see D2).

Why now

Driven by the Codegen unified model — org-mode migration story. The pilot moved party to projects/ores.refdata/modeling/, but projects/ores.refdata/ is an orphan: it has no CMakeLists, no sub-components, no role. Continuing the migration without first regrouping pushes the same orphan into every group. Better to land the regroup now and have every per-group migration task land into a real populated group folder.

Relationship to other stories

Status

Field Value
State DONE
Parent sprint Sprint 19
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-06-02

Regroup complete: all groups moved to ores.<group>/<short>/, Qt under ores.qt/, host as ores.qt/application/, move-invariant include paths; build configures, compiles, and services start and run clean. Shipped in PR #997 along with two pre-existing-breakage fixes surfaced by the clean build (the swap-parse TU and the init-environment service glob). The service-registry consolidation discovered here was promoted to its own story, Consolidate standalone scripts into compass (not a blocker for this story).

Acceptance

  • Every domain product group has a single parent directory at projects/ores.<group>/ containing its api / core / service sub-components under short names.
  • All Qt UI components live under projects/ores.qt/ (the host as application/, each plugin as a short-named sibling); no Qt plugin remains beside its domain group (D2/D3).
  • The flat projects/ores.<group>.<role>/ and projects/ores.qt.<group>/ directories no longer exist.
  • cmake --build --preset linux-clang-debug-make passes; the build output is functionally identical to pre-regroup.
  • ctest passes.
  • Codegen output paths: surveyed — no per-component path references in the profile manifest or templates, so nothing to change (Q4).
  • CI workflows and presets: surveyed — none carried per-component paths. One path-bearing script was missed in the initial survey: build/scripts/init-environment.sh globs projects/ores.*.service to discover NATS services, which the regroup broke (CI "Setup Database" failure). Fixed by reading the existing service registry instead; full consolidation tracked by Consolidate standalone scripts into compass.
  • Include paths made move-invariant (D4) rather than re-pointed to the new absolute layout, so future moves do not re-break them.

Note: the group modeling/ directory is owned by the org-mode migration story, not this one. Orphan modeling/ dirs left by the pilot are left in place for that story to populate.

Tasks

Task State Start End Description
Investigate target layout for component regrouping DONE 2026-06-01 2026-06-02 Decided naming (short), qt under ores.qt/, host as application/, relative includes. Subsumed implementation — regroup done in one pass.

No per-group migration tasks were scaffolded: the regroup is a mechanical, atomic change and was carried out in a single pass under the investigation task. Splitting per group would have created merge churn for no benefit.

Notes

Group-level documentation lives at the group, not at a child

Any documentation that describes the product group as a whole (architecture notes, design overviews, plantuml diagrams covering more than one sub-component, knowledge docs about the domain) lands under projects/ores.<group>/ — typically under projects/ores.<group>/modeling/ alongside the entity models, or a sibling projects/ores.<group>/doc/ if the volume justifies it.

Avoid putting cross-cutting docs under any specific child like projects/ores.<group>.api/: they are no more about the API than they are about the core, and parking them in one child makes the others look like the wrong place to find them. The same logic that drove the regroup itself — "the property belongs to the group, not the children" — applies to documentation too.

Per-component documentation (something genuinely API-specific, or core-specific) still lives in the child component.

Decisions

D1. Child directory naming: short names

Child component directories use short namesapi, core, service, client, server, wrapper, database — under the group parent. Example: projects/ores.refdata/api/, not projects/ores.refdata/ores.refdata.api/. The group folder already disambiguates; the doubled prefix was judged excessive. CMake target names keep the fully-qualified form (ores.refdata.api.lib) for the compiler and linker; only the on-disk folder is shortened. C++ include prefixes are unaffected — they are set by the include/ores.refdata.api/ tree inside each component, which moved intact.

D2. The Qt UI components live under ores.qt/, not the domain group

All Qt UI components are grouped under projects/ores.qt/ rather than beside the domain group they present. Rationale: the Qt plugins are the Application layer projecting the Domain layer — they are not a facet of the domain, they are a separate layer over it. The C++ namespace (ores::qt::refdata), the inter-plugin CMake dependencies (e.g. the scheduler plugin includes the compute plugin), and the precedent of ores.wt.service (a standalone UI, not buried in a domain group) all agree. Plugins keep their namespace-suffix short names: ores.qt/refdata/, ores.qt/admin/, ores.qt/mktdata/, ores.qt/party/, etc.

D3. The Qt host app is ores.qt/application/

ores.qt/ is a pure group folder — no component lives at its root. The MDI host application (formerly the ores.qt component at projects/ores.qt/) moves to projects/ores.qt/application/ as a sibling of all the plugins. This avoids mixing levels (a component at the group root alongside child components) and keeps every child of ores.qt/ a uniform component folder.

D4. Include paths: relative and move-invariant

Self-include references in component src/CMakeLists.txt changed from the fragile absolute form ${CMAKE_SOURCE_DIR}/projects/<fq-name>/include to the move-invariant ${CMAKE_CURRENT_SOURCE_DIR}/../include. The set(ORES_QT_*_DIR ...) self directory variables likewise became ${CMAKE_CURRENT_SOURCE_DIR}/... Cross-component include references were repointed to the new group locations. This removes the class of breakage that the move itself exposed: a future relocation of any component no longer requires editing its own include paths.

D5. Group root CMakeLists (Q3)

Not introduced. projects/CMakeLists.txt continues to add_subdirectory each leaf component directly (now at ores.<group>/<role>). A group-root CMakeLists that factors common settings was judged a separate concern; the build works without it and the regroup stays minimal.

Survey outcomes (Q4, Q5)

  • Codegen output paths: no projects/ores.<group>.<role> references found in the ores.codegen manifests or templates — nothing to change.
  • CI / presets: .github/workflows/ and CMakePresets.json carry no per-component paths — nothing to change.
  • projects/CMakeLists.txt was the only file holding the component add_subdirectory list; all 90+ leaf components updated there.
  • Component src/CMakeLists.txt include paths: ~90 references updated (self → relative, cross → new location).
  • C++ #include directives: unaffected (include/ trees moved intact).

Out of scope

  • Renaming the product groups themselves. refdata, trading, etc. stay as they are; this is purely a directory regrouping.
  • Changing C++ include paths. The headers stay installed under ores.refdata.api/foo.hpp; this is a directory move, not a namespace move.
  • Splitting or merging components within a group. api, core, and service remain three components per group.

Emacs 29.1 (Org mode 9.6.6)