Task: Pilot the combo-field template mechanism for currency's 3 soft-FK fields
This page documents a task in the Reconcile currency Qt custom features with codegen story. It captures the goal, current status, acceptance, and any notes or results.
Goal
Exercise the qt codegen profile's combo-field mechanism for the first
time, end-to-end, using currency's 3 soft-FK detail-dialog fields
(monetary_nature, market_tier, rounding_type). Confirm the
mechanism can drive real reference-table-backed dropdowns as currently
implemented in CurrencyDetailDialog, or find its gaps. If it is not
yet fit for this shape of data, defer piloting it and document the
concrete reason so the parent story's regenerate plan can account for
it.
Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Reconcile currency Qt custom features with codegen |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-07-04 |
Acceptance
- Combo-field mechanism piloted end-to-end for all 3 currency fields, with the generated dropdowns behaving equivalently to the current hand-written ones — OR explicitly deferred with a documented reason.
- Any gaps found in the mechanism itself are recorded, not silently worked around.
Plan
Rather than extend the qt-profile mustache templates directly (the 5 new flags/branches — fetch, reentrancy guard, sort, tooltip, placeholder — would have meant significant new templated C++), wrote one hand-crafted generic helper and kept codegen's job small:
ores::qt::populateDynamicCombo<Entity>(...)in the newores.qt/api/include/ores.qt/DynamicComboSetup.hpp(header-only template): owns the async fetch dispatch, re-entrancy guard (keyed off a watcher object name), sort-by-key, per-item tooltip, "Loading…" placeholder, and selection restore/tooltip-sync — everything previously duplicated three times inCurrencyDetailDialog.cpp.- Three new synchronous fetchers in the existing
ores.qt/api/{include,src}/LookupFetcher.{hpp,cpp}(matching that file's established convention):fetch_rounding_types,fetch_monetary_natures,fetch_currency_market_tiers. These do the actualprocess_authenticated_requestcall and are meant to run insideQtConcurrent::run, same as every otherLookupFetcherfunction. - Currency's
populateRoundingTypeCombo=/=populateMonetaryNatureCombo=/ =populateMarketTierComboinCurrencyDetailDialog.cppnow reduce to ~10-line calls intopopulateDynamicCombo<Entity>, passing the fetcher and small code/tooltip/sort-key lambdas.
Verified by building ores.qt — clean.
Notes
- The old hand-rolled code additionally emitted
errorMessageon fetch failure (distinguishing "fetch failed" from "legitimately empty result"); the new generic helper does not surface that distinction — a failed fetch and an empty table both render an empty combo with no user-visible error. Flagging this as a known gap for the codegen template design (task 3): the template call should likely take an optional error callback, or the helper should return astd::expected<std::vector<Entity>, std::string>instead of a bare vector. - Codegen implication for the next task: rather than generate the 5
behaviours inline, the qt profile only needs to emit, per
is_dynamic_combofield, (a) onefetch_<entity_plural>function inLookupFetcher(small, mechanical, matches existing pattern) and (b) a shortpopulateDynamicCombo<Entity>(...)call in the detail dialog — much smaller codegen footprint than templating the full async/sort/tooltip logic per field.
PRs
| PR | Title |
|---|---|
Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|
Result
Piloted successfully. A new generic populateDynamicCombo<Entity>
helper (ores.qt/api/include/ores.qt/DynamicComboSetup.hpp) plus 3
small LookupFetcher fetchers replace ~300 lines of triplicated
hand-rolled async/sort/tooltip/placeholder logic in
CurrencyDetailDialog.cpp with ~10-line calls each. Build verified
clean. One gap flagged for the codegen plan: fetch-failure signalling
needs a documented decision (silent empty combo vs. surfaced error).