docs: replace SHOWCASE-ROADMAP.md with docs/backlog/ (17 WPs)

Turns the prior roadmap sketch into ordered, gated work packages (enforcement
gates, FP/DDD consistency, CIBG fidelity, Storybook curriculum, a11y) from the
2026-07-02 showcase-hardening audit.
This commit is contained in:
2026-07-02 17:07:59 +02:00
parent a2ed3ae5b8
commit f769242f76
19 changed files with 1326 additions and 94 deletions

View File

@@ -0,0 +1,80 @@
# WP-01 — Axe-on-every-story CI gate
Status: todo
Phase: 0 — enforcement & gates
## Why
The Storybook a11y addon (`@storybook/addon-a11y`, configured in `.storybook/preview.ts`
for `wcag2a, wcag2aa, wcag21a, wcag21aa`) only surfaces violations *interactively*.
Nothing gates CI. This WP turns "a panel you can look at" into "a check that fails the
build", so every story added or changed by later WPs is automatically covered.
## Read first
- `.storybook/main.ts`, `.storybook/preview.ts` (existing a11y config — reuse its tags)
- `.github/workflows/ci.yml` (job layout to extend)
- `package.json` (scripts; note `.npmrc` has `legacy-peer-deps=true`)
## Decisions (pre-made, don't relitigate)
- Mechanism: **`@storybook/test-runner` + `axe-playwright`** against the static build.
The repo uses `@storybook/angular` on the **webpack** builder, which rules out
`@storybook/addon-vitest` (Vite-only). Fallback if test-runner doesn't support
Storybook 10 yet: a hand-rolled Playwright + `axe-core` loop over `storybook-static`
(same gate semantics — document the swap in this file if taken).
- Escape hatch: `parameters: { a11y: { disable: true } }` per story, allowed **only** with
an inline justification comment and a cross-reference to the WP that will fix it
(WP-16/WP-17).
## Files
- `package.json` (devDependencies + scripts)
- `.storybook/test-runner.ts` (new)
- `.github/workflows/ci.yml` (new job)
- Possibly a handful of story/component files for triaged violations
## Steps
1. Check version fit first: `npm view @storybook/test-runner peerDependencies` and pick
the release matching the installed Storybook 10 (`legacy-peer-deps` absorbs minor lag).
2. `npm i -D @storybook/test-runner axe-playwright http-server wait-on concurrently`
(+ `npx playwright install chromium` locally).
3. `.storybook/test-runner.ts`:
- `preVisit`: `injectAxe(page)`.
- `postVisit`: `getStoryContext(page, context)`; skip when
`parameters.a11y?.disable === true`; else `checkA11y(page, '#storybook-root', …)`,
honoring `parameters.a11y.config`/`options.runOnly` from `preview.ts` (don't
duplicate the tag list — read it from the story context).
4. Scripts:
- `"test-storybook": "test-storybook"`
- `"test-storybook:ci": "concurrently -k -s first -n sb,axe \"http-server storybook-static -p 6006 --silent\" \"wait-on tcp:127.0.0.1:6006 && test-storybook --url http://127.0.0.1:6006\""`
5. CI job `storybook-a11y` in `ci.yml`: checkout → setup-node (same version as the
`frontend` job) + npm cache → `npm ci``npx playwright install --with-deps chromium`
`npm run build-storybook``npm run test-storybook:ci`.
6. Run locally against a fresh `build-storybook`; triage violations: fix trivial ones
(labels, roles, contrast via `--rhc-*` tokens); anything structural gets the escape
hatch + comment + WP cross-ref.
7. Update `docs/backlog/README.md`: GREEN now includes `npm run test-storybook:ci`.
## Acceptance criteria
- [ ] `npm run test-storybook:ci` passes locally against a fresh `storybook-static/`.
- [ ] CI has a `storybook-a11y` job; an axe violation makes it fail (verify once with a
deliberately broken story, then revert).
- [ ] Every `a11y.disable` skip carries a justification comment + WP cross-ref.
- [ ] Backlog README GREEN updated.
## Verification
GREEN + `npm run test-storybook:ci`.
## Out of scope
Fixing structural a11y issues in components (WP-16/WP-17); Playwright e2e page sweeps
(explicitly not chosen).
## Risks
- test-runner ↔ Storybook 10 peer mismatch → use the documented fallback.
- Unknown violation count on first run → the escape hatch keeps the WP bounded.