3.8 Board load model — filtered-set + virtualize + over-cap warning (replaces per-column "Load more")
Replace the board’s per-column cursor pagination + "Load more" with the mirror-faithful load model: the board loads its issue set bounded by a hard cap + a Done-age window, virtualizes the render, and shows a "this board is too large — refine the filter" warning when the cap is exceeded — never a per-column "Load more." This is the correction to the scale shape Stories 3.1.4 / 3.2.5 / 3.3.4 / 3.3.5 shipped; those subtasks are NOT edited (what is done is done), and these new subtasks supersede them in code (notes.html mistake #33).
The verified mirror behaviour (rung 1; checked, not asserted). A Jira board renders the whole saved-filter set up to a hard cap (5,000 Software / 3,000 Business), warns "maximum number of viewable issues exceeded — refine your filter" past the cap, windows the Done column to issues resolved in the last ~14 days, and virtualizes long columns — it does NOT paginate columns and has no "Load more"; per-column limits are WIP alerts (3.3.6), not display paging. Per surface (mistake #33): Jira’s issue navigator paginates (so finding #57’s LIST/tree pagination is correct and is NOT touched here); only the board loads-the-set.
What changes. (a) The projection (getBoard) loads each column’s cards up to a board-level cap with the Done-age window for terminal columns, and returns a board-level truncated / cap signal + the existing per-column totals; the per-column cursor + the /columns/[id]/cards load-more route become dead and are retired. (b) The flat board drops the "Load more" button + scroll sentinel + footer and renders the whole bounded set, virtualized (reusing the 2.5.15 useRowWindow). (c) The swimlane board drops the per-column "Load more" footer and buckets the whole bounded set into lanes, virtualized per cell. (d) A board-level over-cap banner ("This board has more than {cap} work items — refine the board filter") renders when truncated, pointing at the Epic-6 board-filter seam (the disabled [Filter] button 3.2 already reserves).
Scale + completeness. This is STILL bounded — it does not "load every row" (finding #57 holds): the cap is the bound, the Done-age window trims terminal columns, and virtualization keeps the DOM bounded. The cap is generous (a real team’s active board fits under it); the rare board that exceeds it gets the warning, exactly as Jira does. The board-filter that would let a user shrink an over-cap board is Epic 6 (board configuration / JQL-style filters); until it lands the banner explains the cap and the [Filter] seam stays disabled — a documented seam, not an invented control.
Out of scope: the board filter / saved-query UI itself (Epic 6); any change to the 3.2.4 move contract, the 3.3 swimlane/cross-lane-drag behaviour, or the 3.3.6 WIP treatment (all unchanged — this story only swaps the load/paging mechanism); the issue list/tree pagination (finding #57, a different surface that correctly paginates — untouched).
Verification
- Pull the Story branch,
pnpm install,pnpm dev, open/boardson the seededmoooon→motirproject. - No "Load more": neither the flat board nor any swimlane shows a "Load more" button or footer; columns render their cards directly and scroll, virtualized (DOM row count stays bounded on a tall column).
- Over-cap warning:
pnpm db:seed:large(a project seeded past the cap) → the board shows the "more than {cap} work items — refine the filter" banner; a normal-sized project shows NO banner. - Done-age window: the Done/terminal column shows only recently-resolved items (the ~14-day window) with the full count still surfaced; older done items are not loaded.
- Swimlanes unchanged otherwise: group-by, collapse, cross-lane drag-reassign, and the WIP over-limit warning all still work (this story changed only loading, not those behaviours).
pnpm test+pnpm test:e2e --grep board-loadgreen over the real stack.