ores.codegen
Table of Contents
Summary
ores.codegen is the project's Python-based code generator. It takes
JSON models and Mustache templates and produces output files —
primarily SQL for the data-quality system, but also C++ scaffolding
for domain types and, since the v2 information architecture, org-mode
documents for the task / story / sprint hierarchy. The generator is
self-contained: a virtualenv, a small set of Python entry points, and
a flat library of templates. Generated files carry standardised
licence headers and editor modelines.
Inputs
- JSON model files under
models/<subject>/. - Mustache templates under
library/templates/— generated artefacts, tangled from the literate facet docs that live alongside them; the Codegen template library overview tops the hierarchy (template ← facet doc ← group doc ← groups overview). - Static data (licences, modelines) under
library/data/. - Optional generator profiles (collections of templates) declared in facet_catalogue.org.
Outputs
- SQL files for data-quality schemas and populates (default).
- C++ scaffolding for domain types (via profile
all-cpp). - Qt scaffolding for entity UIs (via profile
qt). - Information-architecture org documents — task / story / sprint /
version / component — via
generate_doc.sh.
By default, output lands in output/ alongside the wrapper script;
each entry point accepts a custom output directory.
Profile catalogue
C++ profiles are declared in facet_catalogue.org and invoked with
--profile <name>. Each profile is a named collection of Mustache
templates; every template's literate source — prose on role, model
inputs and outputs, plus the tangle block — lives in its facet doc
under the template library. The type mappings that apply across all
profiles are in Entity lifecycle§"Type mappings".
| Profile | Covers | Key library |
|---|---|---|
--profile domain |
Domain class, JSON I/O, table I/O | reflectcpp, libfort |
--profile generator |
Test data generator | faker-cxx |
--profile repository |
Entity, mapper, repository | sqlgen |
--profile service |
Service layer | — |
--profile protocol |
NATS messaging protocol header | — |
--profile sql |
SQL schema, notify triggers, drop scripts | — |
--profile qt |
Qt UI (ClientModel, MdiWindow, dialogs, controller) | Qt6 |
--profile all-cpp |
domain + generator + repository + service + protocol | all above |
--profile all |
all-cpp + sql | all above |
domain
Generates the domain class (a plain struct), JSON I/O, and table I/O.
- JSON I/O: uses
reflectcpp(<rfl/json.hpp>,rfl::json::write()) with custom reflectors fromores.utility/rfl/reflectors.hppto handle types not natively supported (boost::uuids::uuid,std::chrono::system_clock::time_point, etc.). Exposesoperator<<(std::ostream&, const T&). - Table I/O: uses
libfort(<fort.hpp>,fort::char_tablewithFT_BASIC_STYLE) for aligned column output. Type-formatting conventions: UUIDs →boost::uuids::to_string(); booleans → "Y"/"N"; timestamps →std::put_time()as "YYYY-MM-DD HH:MM:SS"; IP addresses →.to_string(). Exposesoperator<<(std::ostream&, const std::vector<T>&).
generator
Generates a test data generator with two static methods:
generate() → one random instance; generate_set(n) → n instances.
Uses faker-cxx for realistic fake field values and
ores.utility/uuid/uuid_v7_generator for UUID fields.
repository
Generates three file pairs: entity, mapper, and repository.
- Entity: a flat struct with
sqlgenannotations that maps to the database table. One domain class does not always map to one entity — consult the model when they diverge. - Mapper: converts entity↔domain via
to_domain()andfrom_domain(). Handles type conversions: UUID strings ↔boost::uuids::uuid, database timestamps ↔std::chrono::system_clock::time_point. - Repository: uses
sqlgenfor database operations andores.database/repository/bitemporal_operations.hppfor all read/write helpers. Write operations use upsert semantics — there is no separate create vs update at the repository layer. Read methods:read_latest(),read_all(),read_latest_since(time_point)(incremental loading),read_at_timepoint(timestamp).
service
Generates the service layer that wraps the repository. Method names
follow the convention in Entity lifecycle§"Service method naming":
save_*, remove_*, find_*, list_*, list_*_since,
get_*_history.
protocol
Generates a single NATS messaging protocol header declaring the request/response types for the entity's pub-sub channels.
sql
Generates SQL table create, notify trigger, and drop scripts. Naming and idempotency conventions are in SQL entity schema patterns.
qt
Generates 12 files: ClientModel, MdiWindow, detail/history dialogs,
controller, and the two .ui form files. Patterns are in
Qt entity patterns and Qt menu and toolbar patterns.
Component scaffold profiles
These profiles create a new component skeleton rather than entity code. They generate CMakeLists, a master header, a stub header+impl, and test harness. See Component architecture for the split model and CMake dep chain.
| Profile | Part | Files |
|---|---|---|
--profile component-api |
ores.COMPONENT.api |
10 (CMakeLists ×4, export.hpp, header, stub header+impl, test main+stub) |
--profile component-core |
ores.COMPONENT.core |
10 (same set, core CMake deps) |
--profile component-service |
ores.COMPONENT.service |
19 (core set + export.hpp + app/config headers+impls + main.cpp) |
--profile component |
standalone (no split) | 10 (generic CMake deps + export.hpp) |
Test fixtures
Component-scaffold integration tests use fixture components under
tests/component_scaffold/. Each fixture is a minimal component tree
that exercises the scaffold profiles end-to-end.
| Fixture | Profile exercised |
|---|---|
| ores.sample_composite | --profile component (group-level composite) |
| ores.sample_composite.api | --profile component-api |
| ores.sample_composite.core | --profile component-core |
Entry points
run_generator.sh— the C++/SQL wrapper. Accepts a model path, an optional output directory, and--template/--profile/--list-profiles.generate_doc.sh— the org-document wrapper. See its CLI indocs/doc_generator.md.src/generator.py— the main Python generator.src/doc_generate.py— the org-document generator.src/fpml_parser.py— FPML Genericode XML → JSON converter.src/iso_generate_metadata_sql.py,src/images_generate_sql.py,src/lei_extract_subset.py— specialised data importers.
Dependencies
- Python 3 with
pystache>=0.6.0(inrequirements.txt). uuidgenon PATH (systemuuid-runtimepackage on Debian/Ubuntu) for the document generator's ID minting.- No runtime dependency on other
ores.*components — the generator is upstream of the C++ tree.
See also
- Model Assisted Software Development — the MASD methodology: logical/physical space, the four metamodels, the six principles, and the backout strategy (pure theory).
- Applied MASD — how ORE Studio instantiates MASD, including the two codegen
routes, the
currencyreference implementation, and the full facet catalogue. - Codegen org-entity meta-model — the single source of truth for the
ores.codegen.entityorg file shape: every section, property, and registered paste block kind (slot UUID → template location → attachment syntax). Read this first when adding a new entity model or a new paste kind. - Codegen template library — the literate template hierarchy: facet groups, facet docs, tangle workflow and drift checks. The group docs: cmake, cpp, sql, doc, assets.
- ores.codegen architecture — directory layout, internal modules, template system, model-template mapping, modeline configuration, features.
- How do I run codegen? — operational recipe for the C++/SQL generator.
- How do I create a new doc? — operational recipe for the org-document generator.
- How do I create a new entity? — end-to-end walkthrough using the codegen profiles to scaffold a new domain entity.
- How do I create a component overview? — recipe for generating a
component overview org document via
generate_doc.sh. - How do I add a new document type? — recipe for extending the document system with a new template and type.
docs/cpp_generation_analysis.md— deep analysis of the C++ generation paths.docs/doc_generator.md— full CLI reference forgenerate_doc.sh.
