feat(webapp): browse the rules, stage 1: kinds with counts, a kind in numbered pages (#1240) #1295
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/1240-browse-rules"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #1240. Built to the owner-signed-off drawing (lane 6e, PR #1292), with their answers: the system's order, pack buttons, numbered pages, and search inside an open kind.
Server (
content_packs.py,app/reference/browse.py,search_service.py):GET /api/game-systems/{key}/reference/kinds?campaign_id=&pack_id=returns the kinds in the display order (5e's ancestry is "Species"), with counts from one grouped COUNT. GM-only records are counted only for a GM, andgm_only/gm_only_totalare given. The visible packs are listed (pack_idnarrows the counts, not the pack list).GET …/reference/page?…&page=&per_page=returns{total, page, per_page, capped, level_range, items}.CANDIDATES= 500.total = min(count, 500)andcappedset.pack_idflows through_matching/count/search, so a count and its list always answer the same question. The existing/referenceroute is unchanged.Page (
Rules.jsx, newui/Pager):<nav aria-label="Pages">witharia-current, 44 px targets on touch, and on/design.kind,page,lvlmin,lvlmax,pack,q), so Back returns to the same page. The empty, failed, capped and no-packs states are covered.Fixed on integration review:
level_rangeas{min: null, max: null}for a kind with no levels, nevernull, which built a bogus option. The test usednull.floor(min)…ceil(max), and "to N" asks for everything below N+1.Wording for the owner: the Wording Review page, part j (j-001 to j-009). It includes making today's search chip say "GMs only" like the rest of the app. Don't merge until it's decided.
Checked:
test_reference_browse(24 new) and related modules, 51 passed on the merged branch. The full suite ran on the server half: 10,411 passed, and the one audit failure was fixed.🤖 Generated with Claude Code
GET /api/game-systems/{key}/reference/kinds (kinds in the system's order with counts, GM-only counted only for a GM, the visible packs) and GET .../reference/page (A-Z without a query and with no 500-record cap on the offset, so every page of a large kind is reachable; ranked and capped at 500 with a query; level range; pack filter). app/reference/browse.py holds the display order and labels (5e's ancestry is "Species"). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>The server's level_range is {min: null, max: null} for a kind with no levels, never null, which made a bogus option; and a 5e challenge rating is fractional, so the selects run from floor(min) to ceil(max) and "to N" asks for everything below N+1. The test now uses the server's real shape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>Render check (2026-10-30), on the seeded journeys stack (Playwright 1.64.1 + axe, on docker-test; the stack is torn down). Campaign: The Lanterns of Cortal (pf2e). A synthetic 120-creature pack was imported through the real API, to get a creature kind and three pages.
Rules & bestiary, as the GM (dana) and a player (joaquin), at 1280×800 and 390×844, light and dark:
?kind=creature&page=2&lvlmin=30&q=gob, Creatures 12, Gob- names onlyEvery one returned HTTP 200, with 0 console errors and no axe violations. At 390 there's no horizontal overflow (page 390/390, filter row 292/292). I looked at the phone shot myself: the stacked filters and the search box are normal height, and the pager sits at the bottom.
/design, where the Pager section shows its three samples: axe reports criticalaria-required-children(2) andaria-valid-attr-value(3), seriouscolor-contrast, and at 390scrollable-region-focusable, across the whole 38,000 px gallery. The Pager itself uses onlyaria-label,aria-current="page"andaria-hiddenon the gaps, so it's unlikely to be the source, but that hasn't been confirmed against main. It's a follow-up, not a blocker for this PR. At 390, a sample with many pages wraps "Next" onto a second line, which is acceptable.Screenshots are in the session's scratchpad (
render1240/).