3.5 Tests — the cross-cutting board journey at scale (load model · drag · swimlanes · WIP)
The Epic-3 integration test story: the COMBINED board journey — bounded load → virtualized render → drag-as-transition → swimlanes → WIP — exercised end-to-end against a few-thousand-issue board, the cross-cutting case every per-story board test explicitly defers here.
Why a separate story (not more per-story tests). Each board story already ships its own closing test subtask covering its surface in isolation: 3.1.7 (projection + move-as-transition over the API), 3.2.7 (board UI render + drag/snap-back + keyboard-DnD), 3.3.7 (swimlane grouping + cross-lane reassign + WIP soft-warning), 3.6.4 (column-config + unmapped→mapped), 3.7.6 (board CRUD + switcher), 3.8.6 (the load-model unit + no-"Load more" assertions). What NONE of them owns — and each one defers to 3.5 by name — is the combined journey at real-team scale, where virtualization, the over-cap bound, the Done-age window, and the interaction surfaces all have to hold at once. That is this story, and only that; it does not re-test what an owning story already proves with a handful of rows.
It MUST reflect the Story-3.8 load model (the headline mandate). Story 3.8 replaced the per-column "Load more" / cursor paging (3.1.4 / 3.2.5 / 3.3.4) with the mirror-faithful Jira model: the board loads its whole filtered set bounded by BOARD_ISSUE_CAP (5,000), virtualizes the render via useRowWindow so the DOM stays bounded, windows terminal columns to DONE_AGE_WINDOW_DAYS (14 days) of recently-resolved issues, and shows the over-cap "refine your filter" banner (OverCapBanner, truncated === true) past the cap — with NO per-column "Load more" anywhere. 3.5's at-scale specs assert exactly this shape (no "Load more" affordance flat OR in swimlanes; the over-cap banner present past the cap and absent under it; the Done-age window trimming the Done column with the full count still on the badge) — never the retired cursor paging.
The fixture + seam this story builds first (3.5.1). The at-scale journey needs a board-shaped large dataset and a cheap way to reach the over-cap / Done-age states. db:seed:large (2.5.16) only builds a tree/list-shaped tenant (it does not spread issues across the board's statuses, assignees, priorities, or epics), and BOARD_ISSUE_CAP / DONE_AGE_WINDOW_DAYS are hardcoded constants. So 3.5.1 ships a board-shaped large seed (issues spread across columns + many swimlane lanes + a Done-age spread) and a test-only, production-inert env seam over the cap + window, so the banner and the Done-age trim are reachable with tens — not thousands — of rows. The journey specs (3.5.2 load model, 3.5.3 interaction) build on that harness.
Out of scope. The Scrum board at scale (sprint-scoped view, Story 4.5) is deferred to Epic 4 (4.7) by 4.5.4 — it needs sprints, and testing it here would point Epic 3 forward into Epic 4 (mistake #32). 3.5 covers the Kanban surface + swimlanes + WIP only. Per-method unit coverage stays in the owning stories; 3.5 is the cross-cutting E2E layer over the real stack.
Verification
- Pull the Story branch,
pnpm install,pnpm prisma generate(NO migration — pure tests + a dev seed script + a test-only env seam over the Story-3.8 schema/services). pnpm db:seed:large(board-shaped variant from 3.5.1) seeds theBIGproject so the board is visibly at scale; sign in as the seed owner and open/boardsto eyeball it (thousands of cards, columns scroll smoothly, no "Load more" anywhere).pnpm test— the at-scale fixture/harness unit checks from 3.5.1 (the board-shaped seed produces the documented column / lane / Done-age distribution; the cap + Done-age env seam flexes under the test env and falls back to the shipped 5,000 / 14 constants when unset).pnpm test:e2e --grep board-at-scale— Playwright over the real stack against the board-shaped large seed:- Load model (3.5.2): the board loads the whole bounded set with NO per-column "Load more" (flat AND swimlane); scrolling a tall column keeps the rendered DOM bounded (virtualization); with the cap lowered below the seeded total the over-cap "refine your filter" banner shows (and is absent when the total is under the cap); the Done column shows only issues resolved inside the Done-age window while its count badge shows the full total.
- Interaction at scale (3.5.3): drag a card across columns deep in a virtualized list → the transition applies (optimistic, reconciled); an illegal cross-column move snaps back (409) with status unchanged; switch group-by to Assignee/Epic/Priority → the board re-lays into many lanes + the catch-all (still bounded, still no "Load more"); a cross-lane drag reassigns the grouped field (and a diagonal drag does both); a column over its WIP limit shows the soft
n/limitwarning yet still accepts the drop (advisory, not blocking).
- All of the above reuse the real-Postgres + Playwright harness (
tests/helpers/db.ts,tests/e2e/_helpers/{db-reset,board,workflow,shell-session}.ts) and DO NOT duplicate the single-surface journeys owned by 3.1.7 / 3.2.7 / 3.3.7 / 3.6.4 / 3.7.6 / 3.8.6.