Story: Reconcile currency Qt custom features with codegen
Table of Contents
This page documents a story in Sprint 22. It captures the goal, current status, acceptance criteria, and the tasks that compose it.
Goal
Bring currency's Qt layer (ores.qt/refdata: ClientCurrencyModel,
CurrencyController, CurrencyMdiWindow, CurrencyDetailDialog,
CurrencyHistoryDialog + .ui files) in line with the current qt
codegen profile, without silently losing any of the real functionality
it has grown beyond the template. Discovered while scoping "Sync Qt
codegen for currency"
(task, blocked on this
story): currency's Qt files are roughly 2x the size of a comparable
already-synced auxiliary entity (~3600 vs ~1900 lines across the 6
hand-written source files), and the excess is real product
functionality, not legacy cruft:
CurrencyMdiWindow: CSV export, XML import/export, and a feature-flagged "generate synthetic test data" button (gated by thesystem.synthetic_data_generationsetting) — none of which exist in any other entity's MDI window or in the template.CurrencyController: extra NATS notification wiring (onNotificationReceived), and handler names that predate the template's current naming convention (onOpenCurrencyVersionvs. the template'sonOpenVersion, etc.).CurrencyDetailDialog(1351 lines vs. ~300 for a synced peer): full version-navigation UI (first/prev/next/last/revert), flag image selection wired throughImageCache, its own generate-button, stale-marking — plus 3 combo-box fields (monetary_nature,market_tier,rounding_type) backed by soft-FK reference tables. The template does have a combo-field mechanism, but no entity in the codebase exercises it yet — currency would be the first, with no working example to mirror.
This story is about deciding, feature by feature, what should become a first-class qt-profile capability (version-navigation UI and CSV/XML import-export look like strong candidates to benefit other entities too) versus what stays currency-specific custom code — before attempting a full regenerate. A blind mechanical sync (the approach that worked cleanly for the C++ core sync task) is not safe here: Qt UI behavior can't be verified without running the app, and the risk of silently dropping a working feature is high.
Status
| Field | Value |
|---|---|
| State | DONE |
| Parent sprint | Sprint 22 |
| Now | All 3 tasks done. Regenerate plan written (per-file table + 9-step sequence); recommends splitting "Sync Qt codegen for currency" into per-step sub-tasks. |
| Waiting on | Nothing. |
| Next | Split "Sync Qt codegen for currency" per the plan and unblock it. |
| Last touched | 2026-07-04 |
Acceptance
- Every feature present in currency's Qt layer but absent from the qt codegen templates is triaged: either promoted to a template capability (with at least currency as a real consumer) or explicitly documented as currency-specific custom code to preserve across regeneration.
- The combo-field template mechanism is either exercised end-to-end for currency's 3 combo fields (piloting it for the first time) or explicitly deferred with a documented reason.
- Once triaged, "Sync Qt codegen for currency" can proceed as a mechanical regenerate + reconcile pass with a concrete, reviewed plan — not a speculative rewrite.
Tasks
| Task | State | Start | End | Description |
|---|---|---|---|---|
| Triage currency Qt custom features against codegen templates | DONE | 2026-07-04 | 2026-07-04 | For each custom feature in currency's Qt layer (CSV/XML import-export, feature-flagged synthetic data generation, full version-navigation UI, flag image handling, NATS notification wiring, handler naming drift), decide feature-by-feature whether it becomes a generalised qt-profile template capability (a variability knob other entities can opt into, e.g. import/export as a configurable capability rather than currency-specific code) or stays currency-specific custom code. As part of the triage, flag and separately note any business logic currently embedded in the Qt UI layer that belongs elsewhere (domain/service/repository) and should be relocated rather than templated in place. Produce a written decision doc covering every discovered feature. |
| Pilot the combo-field template mechanism for currency's 3 soft-FK fields | DONE | 2026-07-04 | 2026-07-04 | Currency's monetary_nature, market_tier, and rounding_type detail-dialog fields are soft-FK combo boxes backed by reference tables, and the qt codegen profile has a combo-field mechanism that no entity currently exercises. Pilot it end-to-end for currency's 3 fields (first real consumer), or explicitly defer with a documented reason if the mechanism is not yet fit for this shape of data. |
| Produce concrete regenerate/reconcile plan for Sync Qt codegen for currency | DONE | 2026-07-04 | 2026-07-04 | Turn the triage and combo-field piloting output into a concrete, reviewed plan for the blocked 'Sync Qt codegen for currency' task: which of the 12 output files change, which template capabilities need to land first, and which currency-specific code must be preserved across regeneration. Once this plan exists, the Qt sync task can proceed as a reviewed mechanical regenerate + reconcile pass rather than a speculative rewrite. |
Decisions
- CSV export, XML import/export, version-navigation UI, and NATS notification wiring: promote to generalised, opt-in qt-profile template capabilities.
- Synthetic-data-generation button: promote as a conditional setting-gated action-visibility knob, generalised beyond this one button.
- Flag image handling: not a promote/custom call — the template
already has a partial generic mechanism (
has_flag_icon) that currency bypasses with hand-rolled code; reconcile currency onto it. - 3 soft-FK combo fields (monetary_nature, market_tier, rounding_type):
rather than extend the mustache templates with 5 new behaviours
(fetch, guard, sort, tooltip, placeholder), wrote one hand-crafted
generic helper,
ores::qt::populateDynamicCombo<Entity>(ores.qt/api/include/ores.qt/DynamicComboSetup.hpp), plus 3 smallLookupFetcherfetchers. Currency's 3 fields now call the helper; builds clean. Codegen's job for this pattern shrinks to emitting one fetcher function and one short call peris_dynamic_combofield. Known gap: fetch-failure signalling isn't surfaced by the helper yet (empty combo either way) — needs a decision in the regenerate plan. - Handler naming drift (
onOpenCurrencyVersionetc.): mechanical rename on regeneration, not a design decision. - Business logic relocation: the random-pick selection logic in
CurrencyDetailDialog::onGenerateClicked()andCurrencyMdiWindow::generateSynthetic()belongs in the generator/service layer, not the Qt UI — relocate during the eventual Qt sync. - Regenerate plan: "Sync Qt codegen for currency" is really 7-8 sub-tasks (relocate business logic; land CSV/XML export, setting- gated visibility, version-navigation UI, and NATS notification- wiring as template capabilities; reconcile flag image and combo fields onto existing/piloted mechanisms; decide fetch-failure signalling; only then the final mechanical regenerate+diff). Split it into per-step sub-tasks rather than attempting one task. Full per-file table and sequence in task.