Story: Codegen developer experience improvements
Table of Contents
This page documents a story in Sprint 27. It captures the goal, current status, acceptance criteria, and the tasks that compose it.
Carried from Sprint 22 as a not-yet-started BACKLOG story.
1. Goal
Fix two of the codegen regenerate workflow's friction points: a component run silently skips models whose type the address does not support, and an entity filter restricts a run to the named entities.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent sprint | Sprint 27 |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-10-13 |
3. Background
The three issues were surfaced during three separate codegen sessions in the
commission_currency sprint:
task_sync_cpp_messaging_codegen_currency_auxiliaries— first observation of the component-wide over-generation and untracked-file cleanup burden.task_sync_qt_codegen_currency_auxiliaries— second observation of over-generation (Qt profile); also first observation of the 13 spurious ERROR lines fromqtprofile againstrefdata-cpp(5 table + 8 junction models).- Both tasks — the impossibility of expressing "regenerate only currency entities" in a single command without listing all three entity names explicitly.
The --entity filter shortcoming was previously captured in
codegen –component run generates all entities not just the target. The
profile/type ERROR downgrade was captured in
Downgrade profile/model-type incompatibility from error to skip in –component mode.
This story groups both with the related entity-group feature into one
deliverable.
4. Acceptance
- A component run produces no ERROR or WARNING for models whose type the address does not support; those models are silently skipped.
- codegen.sh regenerate accepts an entity filter and generates only the named entities, writing no other files to disk.
- All existing codegen runs without the new flags produce identical output to before.
- codegen.sh –help and the profile documentation list the new filter flag.
5. Tasks
| Task | State | Start | End | Description |
|---|---|---|---|---|
| Downgrade address/model-type incompatibility to skip in –component mode | DONE | 2026-07-26 | 2026-07-27 | In generator.py, detect model-type/address incompatibility in –component mode and skip silently (DEBUG log) rather than emitting ERROR and incrementing the error counter. Keep ERROR for explicit single-entity invocations. |
| Add –entity filter flag to codegen.sh regenerate | DONE | 2026-07-27 | 2026-07-29 | Implement an –entity (or –entities) flag that restricts a –component run to the named entities only. No other entity files are generated or written to disk. |
| Task: Add entity group / tag system to model and codegen CLI | BACKLOG | Design and implement a group annotation (e.g. :group: in entity org files or a groups section in the component manifest). Expose –group flag on codegen.sh regenerate. Define the initial currency group in ores.refdata. | ||
| Fix refdata entity model drift: update to latest format and regenerate | DONE | 2026-07-29 | 2026-07-30 | Several refdata entities' checked-in generated code has drifted from what current codegen templates/models produce (discovered while verifying zero-diff for the literate-template-block-commentary task: country_repository.cpp, country_service.cpp, ClientCountryModel.cpp, CountryDetailDialog.cpp, CountryMdiWindow.cpp, country_protocol.hpp, country_handler.hpp all show diffs on regen even with unmodified templates). Update every refdata entity org model to the latest format/conventions, regenerate all of them, and commit the resulting drift so the tree is clean before further template work lands. |
| Fix synthetic entity model drift: update to latest format and regenerate | DONE | 2026-07-30 | 2026-07-30 | Following the same pattern as the refdata sweep (task fix-refdata-model-drift): regenerate every ores.synthetic domain_entity and junction model against current codegen templates, updating any model found using an outdated format/convention before regenerating, and commit the resulting drift-free tree. compass build and rat must pass after. |
| Fix marketdata entity model drift: update to latest format and regenerate | DONE | 2026-07-30 | 2026-07-30 | Following the same pattern as the refdata sweep (task fix-refdata-model-drift): regenerate every ores.marketdata domain_entity and junction model against current codegen templates, updating any model found using an outdated format/convention before regenerating, and commit the resulting drift-free tree. compass build and rat must pass after. |
| Fix dq entity model drift: update to latest format and regenerate | DONE | 2026-07-30 | 2026-07-30 | Following the same pattern as the refdata sweep (task fix-refdata-model-drift): regenerate every ores.dq domain_entity and junction model against current codegen templates, updating any model found using an outdated format/convention before regenerating, and commit the resulting drift-free tree. compass build and rat must pass after. |
| Fix scheduler entity model drift: update to latest format and regenerate | DONE | 2026-07-31 | 2026-07-31 | Following the same pattern as the refdata sweep (task fix-refdata-model-drift): regenerate every ores.scheduler domain_entity and junction model against current codegen templates, updating any model found using an outdated format/convention before regenerating, and commit the resulting drift-free tree. compass build and rat must pass after. |
| Fix workspace entity model drift: update to latest format and regenerate | ABANDONED | 2026-10-05 | Following the same pattern as the refdata sweep (task fix-refdata-model-drift): regenerate every ores.workspace domain_entity and junction model against current codegen templates, updating any model found using an outdated format/convention before regenerating, and commit the resulting drift-free tree. compass build and rat must pass after. | |
| Name the capture when a task has no sprint story | DONE | 2026-10-07 | compass pr create refuses a task whose story is a backlog capture with only No story.org next to task. The workflow is that a capture is promoted into the sprint before it takes a task or a PR, so say that, name the capture, and give the promote command. | |
| Read every result section before refusing a merge | DONE | 2026-10-07 | A task doc with an empty * Result heading above a written one made compass pr merge refuse with 'result section is empty' while the prose sat directly below it. Read every section and treat the result as present when any carries prose, and name the duplicate. | |
| Make the drift check script executable | DONE | 2026-10-07 | check_component_drift.py is mode 644, so the literal command the documents give exits 126 with no output. Give it the execute bit and, if a gate can, keep it. |
6. Decisions
The remainder is carried in Add entity groups and finish the remaining codegen work.
- Wording updated at sprint 23 pull-in (2026-07-11). Originally written
against
--profile=/–component=; reworded to--addressto match the CLI after Resolve codegen model unification blockers' B5 landed. If that story's B4 (collapserefdata=/=refdata-cpp) lands first,--component refdata-cppcollapses to--component refdata— update examples accordingly when picking up this story's first task. - Error vs. skip boundary. Incompatible-type encounters are an error only when
the caller explicitly names an entity (
--entity rounding_type --address ores.cpp.qton atablemodel). In--componentmode the codegen discovers entities automatically and must handle heterogeneous types gracefully. - Group granularity. The group concept should live in the entity model (org file property or a manifest section), not in the codegen CLI, so that it is co-located with the model and does not require CLI changes when the group membership changes.
- –entity vs. –group. Both flags are needed.
--entityis for ad-hoc one-off targeting without modifying the model.--groupis for repeatable domain-scoped regeneration that reflects how the business thinks about entity ownership. - counterparty's logo/flag facet already existed; it just wasn't wired
up. The "Bring counterparty's Qt logo/flag picker under codegen"
backlog item assumed the facet needed building from scratch. It
didn't –
:flag_icon_column:already drives it (currencyuses it);counterparty's model was simply missing the property. Adding it and regenerating restored the feature byte-for-byte.partyhad the identical gap, fixed the same way. That backlog item's premise is stale; worth re-triaging before picking it up. - scheduler's
job_definitionis hand-diverged across every layer, not just SQL. Unlikeparty(hand-maintained SQL only, other facets safe to regen),job_definition's domain column shapes (tenant_id=/=schedule_expression=/=is_active) don't match the hand-written struct's actual types (std::optional<boost::uuids::uuid>=/=cron_expression=/=bool), so even domain/repository-entity/mapper regen would emit wrong types. Its repository and messaging layers are also hand-maintained, with cross-component consumers (ores.reporting). No facet is currently safe to regenerate; the model file documents the exclusion in full rather than a full regen being attempted. Needs a proper resync (fixing column shapes, re-adding the hand-written operations to the generated surface) before any facet can be regenerated.
7. Out of scope
- Changing which profiles support which model types (that is a profile design question, not a DX question).
- Per-entity profile overrides (specifying a different profile for individual entities within a component run).
- Automatic discovery of which entities in a component have drifted (that belongs
to the
refactor_codegen_cppstory).