feat(web): board view with HTMX load more pagination (ATB-28) (#45)
* docs: add try block granularity guidance to error handling standards
When a single try block covers multiple distinct operations, errors from
later steps get attributed to the first — misleading for operators
debugging production failures. Document the pattern of splitting try
blocks by failure semantics, with a concrete example from ATB-28.
* docs: add ATB-28 board view design doc
* docs: add ATB-28 board view implementation plan
* feat(web): add timeAgo utility for relative date formatting
* feat(web): add isNotFoundError helper for AppView 404 responses
* feat(appview): add GET /api/boards/:id endpoint
Adds single board lookup by ID to the boards router, with 400 for
invalid IDs, 404 for missing boards, and 500 with structured logging
for unexpected errors.
* feat(appview): add pagination to GET /api/boards/:id/topics
Adds optional ?offset and ?limit query params with defaults (0 and 25),
clamps limit to 100 max, and returns total/offset/limit in response
alongside topics. Count and topics queries run in parallel via Promise.all.
* feat(appview): add GET /api/categories/:id endpoint
* feat(web): implement board view with HTMX load more pagination
- Replace boards.tsx stub with full two-stage fetch implementation:
stage 1 fetches board metadata + topics in parallel, stage 2 fetches
category for breadcrumb navigation
- HTMX partial mode handles ?offset=N requests, returning HTML fragment
with topic rows and updated Load More button (or empty fragment on error)
- Full error handling: 400 for non-integer IDs, 404 for missing boards,
503 for network errors, 500 for server errors, re-throw for TypeError
- Add 19 comprehensive tests covering all routes, error cases, and HTMX
partial mode; remove 3 now-superseded stub tests from stubs.test.tsx
* fix(web): make board page Stage 2 category fetch non-fatal
Category name lookup for breadcrumb no longer returns a fatal error
response when it fails — the board content loaded in Stage 1 is shown
regardless, with the category segment omitted from the breadcrumb.
* docs(bruno): add Get Board and Get Category; update Get Board Topics with pagination
* docs: mark ATB-28 board view complete in project plan
* fix(web): remove unused unauthSession variable in boards test
* fix: add 500 error tests for GET /api/boards/:id and GET /api/categories/:id; log HTMX partial errors