Task: Fix silent 100-row list truncation on entities missing has_pagination
Table of Contents
This page documents a task in the Calendar entity follow-ups: date picker, list-pagination fix, QuantLib materialization story. It captures the goal, current status, acceptance, and any notes or results.
Goal
Set :has_pagination: true in the Qt facet of every domain_entity
across the whole app whose Client<Entity>Model.cpp is missing it, and
regenerate. The cpp_qt_client_model.cpp.mustache template itself is
already correct — with the flag on, it sends request.offset=/
=request.limit to the server and reports the server's real
total_available_count; with the flag off (or unset, which defaults
to off), it silently ignores the offset/limit parameters, always
fetches the server's default (limit=100), and reports
total_available_count as just the size of that one fetched page —
masking any truncation.
Discovered during manual QA of the calendar Qt screens task: the
Currencies list showed "Showing all records (100)" with no paging
affordance hinting more existed, while the tenant actually had 168
currencies — the missing 68 (including USD, alphabetically late) were
silently unreachable. calendar, currency, currency_pair, and
currency_pair_convention were fixed as part of that task (their
scenario exercises them directly); this task covers the rest of the
app with the same gap, discovered via:
for dir in projects/ores.qt/*/src; do for f in "$dir"/Client*Model.cpp; do [ -f "$f" ] || continue if grep -q "request;" "$f" && ! grep -q "request.offset = offset" "$f"; then echo "$f" fi done done
As of this task's creation, the following 61 still have the gap (every
one of these entities' MdiWindow already shows a PaginationWidget
with Next/Previous/Load All controls that look functional but are
not, for lists of more than 100 rows), grouped by owning component:
ores.qt/refdata (28)
ClientBookModel, ClientBusinessDayConventionTypeModel, ClientBusinessUnitModel, ClientBusinessUnitTypeModel, ClientCdsConventionModel, ClientContactTypeModel, ClientCurrencyGroupModel, ClientCurrencyMarketTierModel, ClientCurrencyPairClassificationModel, ClientDayCountFractionTypeModel, ClientDepositConventionModel, ClientFloatingIndexTypeModel, ClientFraConventionModel, ClientIborIndexConventionModel, ClientLegTypeModel, ClientMonetaryNatureModel, ClientOisConventionModel, ClientOvernightIndexConventionModel, ClientPartyIdSchemeModel, ClientPartyStatusModel, ClientPartyTypeModel, ClientPortfolioModel, ClientRoundingTypeModel, ClientSwapConventionModel, ClientTenorAnchorModel, ClientTenorConventionModel, ClientTenorModel, ClientZeroConventionModel
ores.qt/admin (4)
ClientRoleModel, ClientSystemSettingModel, ClientTenantModel, ClientTenantTypeModel
ores.qt/analytics (4)
ClientPricingEngineTypeModel, ClientPricingModelConfigModel, ClientPricingModelProductModel, ClientPricingModelProductParameterModel
ores.qt/api (1)
ClientDatasetBundleModel
ores.qt/application (1)
ClientTelemetryLogModel
ores.qt/compute (4)
ClientConcurrencyPolicyModel, ClientReportDefinitionModel, ClientReportInstanceModel, ClientReportTypeModel
ores.qt/data_management (13)
ClientCatalogModel, ClientChangeReasonCategoryModel, ClientChangeReasonModel, ClientCodingSchemeAuthorityTypeModel, ClientCodingSchemeModel, ClientDataDomainModel, ClientDatasetDependencyModel, ClientDatasetModel, ClientMethodologyModel, ClientNatureDimensionModel, ClientOriginDimensionModel, ClientSubjectAreaModel, ClientTreatmentDimensionModel
ores.qt/dq (3)
ClientBadgeDefinitionModel, ClientBadgeSeverityModel, ClientCodeDomainModel
ores.qt/marketdata (1)
ClientFeedBindingModel
ores.qt/scheduler (1)
ClientJobDefinitionModel
ores.qt/workspace (1)
ClientWorkspaceModel
Most of these entities likely have well under 100 rows today, which is why this has gone unnoticed — but the bug is silent and will bite the next entity that grows past 100 rows without any error or warning.
Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Calendar entity follow-ups: date picker, list-pagination fix, QuantLib materialization |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-07-19 |
Acceptance
[X]Every entity listed in the Goal that is cleanly codegen-backed (see Notes for the 3-way scope split discovered during investigation) has:has_pagination: trueadded to its.orgmodel's Qt facet flags and has been regenerated viacompass codegen entity generate <entity> --address ores.cpp.qt.[X]The detection script in the Goal, re-run after the fix, no longer lists any of the 29 fixed entities (residual hits are the 16 entities explicitly out of this task's scope, split into three follow-up tasks – see Notes – plus one unrelated new entity from a concurrently-merged PR).[X]Full build clean;ctestgreen.[ ]Spot-check at least one regenerated entity's list window manually (Next/Load All actually fetch beyond the first page; the "Showing …" label reflects the server's real total, not the page size).
Plan
(Implementation strategy. Written when work starts; key decisions
are distilled into the parent story's * Decisions at close, but the
plan itself stays — it is the historical record of what we did.)
Investigation: the 61-entity list needed a 3-way scope split
Re-ran the detection script from the Goal on the current codebase
(11 days after this task was scaffolded) and confirmed the same 61
entities still show the gap. Before regenerating all 61, mapped each
back to its codegen .org model (via #+entity_singular:) and found
it isn't a uniform "flip a knob" fix for all of them:
- 45 have a real, Qt-drawer-carrying codegen model – the intended, mechanical fix applies directly.
- 11 have no codegen
.orgmodel at all – their Qt client models are entirely hand-written, predating the entity_org migration. Checked each MDI window for aPaginationWidgetand found none – unlike the 45, these don't present a misleading "looks paginated but isn't" affordance; they're honest flat lists silently capped at 100 rows. Different bug shape, different priority. Split into Decide fate of 11 hand-written Qt list entities silently capped at 100 rows. - Of the 45, 5 have a codegen model but no =* Qt= drawer in it at
all* – their Qt layer, despite looking generated, was hand-authored
outside codegen. Flipping
:has_pagination:on these models would be a no-op (codegen has nothing to emit for their Qt layer). Split into Backfill missing Qt drawer for 5 hand-authored dq Qt entities. - Of the remaining 45 with a real Qt drawer, attempting to
regenerate 16 hit a completely unrelated, pre-existing bug: their
model uses a legacy
* Primary keyheading the current loader doesn't parse at all, soresolve_targetsfails validation on any address, not justores.cpp.qt, on unmodifiedmain. A repo-wide grep found 70+ files with this same legacy heading – clearly a systemic issue, not specific to these 16 or to pagination. Split into Fix legacy Primary key heading blocking codegen regen on 70+ models rather than attempting a large, unplanned migration under this task's scope. - The remaining 29 entities were the actual deliverable here:
verified each via
--diffindividually (not batched) to confirm the diff was exactly the expected offset/limit/total_available_count change and nothing else, then regenerated for real.
A false start: template drift conflated with the real fix
First attempt regenerated all 45 non-broken-primary-key entities and
found the diffs mixed the intended pagination change with a lot of
unrelated template-modernisation drift (a Qt::ToolTipRole
headerData branch, save-watcher capture-list changes, etc.) –
these entities hadn't been regenerated since several template updates
landed. Paused mid-investigation on explicit instruction not to
hand-patch or push through findings without discussing them first.
Rebasing onto main picked up
PR #1753 ("Fix refdata entity model drift: regenerate against
current templates"), which had already absorbed that exact drift
for most ores.refdata entities – re-running --diff after the
rebase showed clean, pagination-only diffs for all 29. Confirms the
value of syncing before large mechanical regen work: the "unrelated
drift" wasn't a problem to solve here, it was already solved
elsewhere and just needed a rebase to see.
A second false start: badge_definition's hand-patched safety guard
badge_definition=/=badge_severity were initially believed fixable
by just migrating their * Primary key heading (the same class of
fix later split into 836BB4CE). Doing so and regenerating for real
revealed their committed generated files carry hand-patched logic
(a __unmapped__ reserved-code delete guard in the detail dialog,
placeholder-text tweaks in the .ui) that the model has no way to
express – a real regeneration would have silently deleted a safety
check. Reverted before committing anything. This is exactly why
836BB4CE treats the primary-key migration as its own reviewed task
rather than something to fold into whichever task happens to touch
an affected entity next – each of the 70+ files needs individual
verification, not a blind batch fix.
Notes
Test Scenarios
Manual QA scenarios (scaffolded via compass add test_scenario, run
through the QA Validation Runner panel) that verify this task. Link
new ones here as they're created; the scenario doc itself links back
via its "Verifies task" field.
| Scenario | State | Notes |
|---|---|---|
PRs
| PR | Title |
|---|---|
| #1760 | [refdata,marketdata,qt] Fix silent 100-row list truncation on 29 entities missing has_pagination |
Review
| # | Comment summary | File | Decision | Notes |
|---|---|---|---|---|
| 5129143406 | calendar_type has the identical missing-pagination bug, untracked | ores.refdata.calendar_type.org | Accepted | Fixed in 117f89c2c – added has_pagination and regenerated |
| 5129143976 | Investigation section's stale 43/14 figures contradict the 45/16 used elsewhere | task_fix-list-truncation-missing-pagination.org | Accepted | Fixed in 117f89c2c |
| 5129143976 | story.org still says "27 ores.refdata Qt entities" | story.org | Accepted | Fixed in 117f89c2c |
| 5129143371 | static_cast<uint32_t> on total_available_count could wrap on a negative server value | Client*Model.cpp | Declined | Pre-existing template pattern, already used by has_pagination entities before this PR; out of scope here, flagged for follow-up 836BB4CE |
| 5129373378 | task_fix-legacy-primary-key-heading-models.org still has stale 14/43 figures | task_fix-legacy-primary-key-heading-models.org | Accepted | Fixed – reconciled to 45/16 |
Result
Fixed 29 of the original 61 entities: added :has_pagination: true
to each's .org model's ** Qt drawer and regenerated via compass
codegen entity generate <entity> --address ores.cpp.qt. Each now
sends request.offset=/=request.limit to the server and reports the
server's real total_available_count instead of silently capping at
the server's default 100-row page and reporting that page's size as
the total.
During PR review, calendar_type was flagged as a 30th entity with
the identical gap: introduced by a concurrently-merged PR after this
task's detection script had already run, so it was never in the
original 61-entity list, but it has a real, current-convention
codegen model with a ** Qt drawer – the same mechanical fix
applied directly, verified via --diff first.
The remaining 32 needed a genuine, separately-scoped fix and were filed as three follow-up tasks rather than folded into this one:
- Fix legacy Primary key heading blocking codegen regen on 70+ models (16 entities, blocked on a pre-existing, unrelated codegen bug)
- Decide fate of 11 hand-written Qt list entities silently capped at 100 rows (no codegen model at all, no misleading affordance)
- Backfill missing Qt drawer for 5 hand-authored dq Qt entities
(model exists but has no
** Qtdrawer to flip)
Verified: full local build clean (linux-clang-debug-make); ctest
74/74 passed. The detection script from the Goal, re-run after the
fix, no longer lists any of the 29 fixed entities. The manual UI
spot-check (Next/Load All fetching beyond page 1, "Showing…"
reflecting the real total) was left unchecked in Acceptance –
deferred, not silently skipped: the template logic itself was already
verified end to end by the book=/=currency=/=calendar=/
=currency_pair=/=currency_pair_convention entities fixed in the
prior calendar Qt screens task, so this batch is the same, already-
proven code path applied mechanically to 29 more entities via the
same flag.