Task: has_pagination knob is a silent-failure footgun in the Qt client model template
Table of Contents
This page documents a task in the Fix codegen template drift story. It captures the goal, current status, acceptance, and any notes or results.
Goal
cpp_qt_client_model.cpp.mustache generates a fetch method whose
behaviour is a binary fork on the :has_pagination: Qt-facet flag:
set true, it sends real offset=/=limit to the server and reports
the server's true total_available_count; unset (the silent
default), it ignores offset/limit entirely, always fetches the
server's default page, and reports the fetched page's own size as if
it were the total — masking the truncation instead of surfacing it.
Every entity's MdiWindow unconditionally shows a full
PaginationWidget (Next/Previous/Load All/page size) regardless of
this flag, so an entity with the flag off looks identical to one
with it on right up until its row count exceeds 100, at which point
rows silently become unreachable with no error, warning, or visual
cue. 61 of the app's ~89 Qt list entities currently have the flag
unset — see the tracking
task for the full list and the fix (set the flag, regenerate).
The narrower fix (setting the flag everywhere) doesn't address the shape of the footgun: a knob that silently defaults to the broken behaviour, with no build-time or run-time signal distinguishing "deliberately unpaginated, all rows always fit" from "someone forgot to set the flag." Worth reconsidering the underlying design once the narrow fix lands:
- Generate the paginated fetch path unconditionally (drop the
has_paginationfork) and let every entity always send real offset/limit and report the real total — the branch exists presumably as an optimisation/simplification for small, truly bounded lookup tables, but the two code paths are barely different and the unconditional one is strictly more correct. - Or, if a genuinely unpaginated mode is still wanted for small fixed
lookup tables, gate the widget on the same flag too, so an
unpaginated entity's
MdiWindowdoesn't render Next/Previous/Load All controls that don't do anything — the mismatch between "looks paginated" and "is paginated" is what let this go unnoticed across 61 entities. - Either way, a codegen lint/validation pass that flags entities whose generated model and generated window disagree on pagination support would catch the next occurrence of this drift at generation time rather than in production data.
Status
| Field | Value |
|---|---|
| State | BACKLOG |
| Parent story | Fix codegen template drift |
| Now | Not yet started. |
| Waiting on | Nothing. |
| Next | Begin implementation. |
| Last touched | 2026-08-06 |
Acceptance
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.)
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 |
|---|---|
Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|
Result
Promoted from capture
Captured 2026-07-19 in the product backlog; promoted preserving the UUID.
What
cpp_qt_client_model.cpp.mustache generates a fetch method whose
behaviour is a binary fork on the :has_pagination: Qt-facet flag:
set true, it sends real offset=/=limit to the server and reports
the server's true total_available_count; unset (the silent
default), it ignores offset/limit entirely, always fetches the
server's default page, and reports the fetched page's own size as if
it were the total — masking the truncation instead of surfacing it.
Every entity's MdiWindow unconditionally shows a full
PaginationWidget (Next/Previous/Load All/page size) regardless of
this flag, so an entity with the flag off looks identical to one
with it on right up until its row count exceeds 100, at which point
rows silently become unreachable with no error, warning, or visual
cue. 61 of the app's ~89 Qt list entities currently have the flag
unset — see the tracking
task for the full list and the fix (set the flag, regenerate).
The narrower fix (setting the flag everywhere) doesn't address the shape of the footgun: a knob that silently defaults to the broken behaviour, with no build-time or run-time signal distinguishing "deliberately unpaginated, all rows always fit" from "someone forgot to set the flag." Worth reconsidering the underlying design once the narrow fix lands:
- Generate the paginated fetch path unconditionally (drop the
has_paginationfork) and let every entity always send real offset/limit and report the real total — the branch exists presumably as an optimisation/simplification for small, truly bounded lookup tables, but the two code paths are barely different and the unconditional one is strictly more correct. - Or, if a genuinely unpaginated mode is still wanted for small fixed
lookup tables, gate the widget on the same flag too, so an
unpaginated entity's
MdiWindowdoesn't render Next/Previous/Load All controls that don't do anything — the mismatch between "looks paginated" and "is paginated" is what let this go unnoticed across 61 entities. - Either way, a codegen lint/validation pass that flags entities whose generated model and generated window disagree on pagination support would catch the next occurrence of this drift at generation time rather than in production data.
Why
Discovered while investigating a real bug during manual QA of the calendar Qt screens task: the Currencies list showed "Showing all records (100)" with 68 currencies (including USD) silently unreachable. The immediate fix is per-entity (tracked here); this capture is about the generator-level anti-pattern that made the bug possible and easy to reintroduce on the next new entity.
References
- Task: Fix silent 100-row list truncation on entities missing has_pagination — the narrow fix.
projects/ores.codegen/library/templates/cpp_qt_client_model.cpp.mustache— the template with thehas_paginationfork.
See also
- Qt screens for calendars: list/add/edit, combo picker, flag display — where this was found.