Task: Implement currency_pair and currency_pair_convention via ores.codegen.entity
This page documents a task in the Currency pair support in reference data story. It captures the goal, current status, acceptance, and any notes or results.
Goal
Model currency_pair (identity), currency_pair_convention (1:1
quoting/date conventions), and their two new aux types
(currency_pair_classification, currency_group) plus the
currency_currency_group junction, via ores.codegen.entity=/
=ores.codegen.junction, per the settled field design. Generate and
reconcile SQL, C++ core, messaging, and Qt profiles until the
component builds cleanly. CLI/shell profiles are a separate,
pre-existing codegen gap (tracked elsewhere), not blocking this task.
Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Currency pair support in reference data |
| Now | All 5 entities modelled, generated (SQL/C++/messaging/Qt), and building cleanly. |
| Waiting on | Nothing. |
| Next | Resume the migrate-off-fx-convention task; run compass db recreate to verify SQL end-to-end. |
| Last touched | 2026-07-06 |
Acceptance
[X]currency_pair, currency_pair_convention, currency_pair_classification, currency_group, and currency_currency_group_junction modelled asores.codegen.entity=/=ores.codegen.junction.[X]SQL, C++ core (domain/generator/repository/service), messaging (protocol/nats-eventing/nats-handler), and Qt profiles generated for all 5.[X]currency_pair's base/quote/settlement currency fields use the new flagged_combo Qt facet (flag icons via FlagIconHelper).[X]currency_pair's list column shows a composited base+quote flag icon via the existing generic icon_columns facet.[X]ores.refdata.api.lib, ores.refdata.core.lib, ores.qt.refdata.lib, and both test targets build cleanly.[ ]compass db recreate run to verify the generated SQL applies cleanly end-to-end (not yet done this session).
Plan
Read the settled field design from the three prior design tasks
(entity model, currency-group replacement, identity/convention split), then
diffed the target shape against currency.org's own knobs (change-
reason variability, Qt has_change_reason_cache, table display,
insert-trigger validations table) to make sure nothing "standard" was
missing, per explicit instruction mid-task.
Discovered the desired UX (flag-icon currency pickers) had no working
codegen path: is_dynamic_combo exists in core.py but was never wired
to the actual async fetch helper (populateDynamicCombo<Entity>,
hand-invoked only in CurrencyDetailDialog.cpp); the real working
precedent for flag-icon currency pickers
(FlagIconHelper::apply_flag_icons + fetch_currency_codes) is 100%
hand-written across ~10 trading forms. Per project convention (paste
blocks only for genuinely one-off cases), added a new generic Qt
facet, flagged_combo, to core.py + the three detail-dialog templates
(header=/=ui=/=impl .org sources, tangled to .mustache) rather than
a paste block, since the pattern already existed identically elsewhere.
currency_pair's list-column composited flag icon needed no new work —
icon_columns already supported the two-field case generically (its own
docstring cites "e.g. a currency pair" as the motivating example).
Generation surfaced two pre-existing core.py bugs, both fixed:
needs_counter read the primary key's derived is_text flag before it
was computed (always False), and was scoped inside an
if 'natural_keys' in domain_entity block that currency_pair (no
natural keys) never entered — so a text-PK entity with a custom
generator and no natural keys never got its uniqueness-suffix counter
declared, a compile error. Also found protocol.hpp (a hand-maintained
per-component aggregator of every entity's own protocol header) needed
new =#include=s added by hand for the 4 new entities — codegen doesn't
touch that file.
Modelling decisions of note: classification and fixing_source stayed
free-text line-edits rather than dynamic combos — no working codegen
path exists yet for aux-type reference-data combos either (separate,
already-captured gap, see codegen_flagged_dynamic_combo.org). Dropped
an initial points_factor() computed-method design (no paste point
exists on the generated domain struct, only repository/service) in
favour of deferring the reciprocal computation to the future ORE
mapper, which can just inline 1.0 / pip_factor.
Notes
Two follow-ups deliberately left out of scope for this task:
- The composited pair-flag list column reads correctly-sized only if
the generated
CurrencyPairMdiWindow's list view callssetIconSize(currency_pair_icon_size())(seeFlagIconHelper.hpp) — no codegen facet sets this yet; FX Spot Grid does it by hand today. Not done here; the column will render with Qt's default (squarish) icon size until addressed. compass db recreatehasn't been run this session to verify the generated SQL create/drop scripts apply cleanly against a live database — build-level compilation was verified, not the DB schema itself.
PRs
| PR | Title |
|---|---|
Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|