feat(web): close TEST-H3 — install Storybook 10 + wire scripts + dropt tsconfig exclude

Closes frontend-design-audit finding TEST-H3 (High):

  Zero Storybook — 9 production components live without isolated
  rendering or designer-handoff surface

Phase 8 originally shipped the scaffold (.storybook/main.ts +
preview.ts + 8 *.stories.tsx files) but couldn't land the deps:
  • Storybook 8.6 peer-capped at Vite 6, project ships Vite 8
    (Phase 4 manualChunks rewrite). Hotfix #9 ripped the deps.
  • The .storybook/main.ts header speculated "Storybook 9 supports
    Vite 7+8" — that was wrong. Verified at install time today:
    Storybook 9.1.20's peer range is Vite 5/6/7. ERESOLVE'd again.
  • Storybook 10.4.0 is the first release with explicit Vite 8 in
    its peer range (^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0). Installed
    cleanly via `npm install --save-dev`.

═══════════════════════════ CHANGES ═══════════════════════════════

package.json + package-lock.json:
  • storybook ^10.4.0
  • @storybook/react-vite ^10.4.0
  • @storybook/addon-a11y ^10.4.0
  All resolve without --legacy-peer-deps. 93 packages added.
  Scripts: `npm run storybook` (dev server on :6006) and
  `npm run storybook:build` (→ .storybook-static).

tsconfig.json:
  Dropped the `src/**/*.stories.tsx` + `src/**/*.stories.ts`
  exclusions. Storybook 10's @storybook/react types are stable;
  the 8 committed story files typecheck cleanly inside the main
  `npm run build` step. Phase 8's "stories excluded so build stays
  green in the meantime" caveat is now retired.

web/src/components/Banner.stories.tsx:
  Fixed stale prop name: stories used `severity: 'error'` but the
  Banner primitive's prop is `type: 'error'` (BannerType union).
  4-line edit, replace_all on `severity:` → `type:`. The Banner
  component never had a `severity` prop — the story was authored
  against a different draft of the API. Typecheck now passes.

web/.storybook/main.ts:
  Replaced the "deps not installed" header block with a
  version-selection history block documenting the 8 → 9 → 10
  trail so the next operator who upgrades Vite doesn't re-walk
  the same wall.

.gitignore:
  Added `web/.storybook-static/` (Storybook build output, like
  web/dist/).

═══════════════════════════ VERIFICATION ═══════════════════════════

  • npm install — exit 0, 93 packages, no peer warnings, no
    ERESOLVE.
  • npx tsc --noEmit — exit 0 with stories included (was running
    excluded; now they're in the typecheck graph).
  • npx storybook build — built in 3.09s, 17 chunks emitted to
    .storybook-static. All 8 stories rendered without errors.
  • npx vitest run src/components — 16 files / 161 tests pass
    (no regression from Storybook install / story-file fix).
  • npx vite build — production build green in 3.35s.
  • CI guards: no-raw-table 17/17, no-unbound-label 134/134,
    no-raw-toLocaleString clean.

Operator follow-ups (none blocking):
  • `npm run storybook` locally opens the dev server with hot-
    reload + addon-a11y panel.
  • `npm run storybook:build` for an immutable static deploy
    (e.g. cert-ctl.io/storybook).
  • New components SHOULD ship a sibling *.stories.tsx going
    forward; can wire a CI guard if desired (fe-component-has-
    story.sh — scaffold mentioned in the audit's executable
    prompt for Phase 8 TEST-H3 but deferred).

Ground-truth: origin/master tip bc417fc (UX-M9 just pushed)
verified via GitHub API BEFORE commit.
This commit is contained in:
shankar0123
2026-05-14 19:59:08 +00:00
parent bc417fc458
commit 622c19cafe
6 changed files with 2442 additions and 24 deletions
+1
View File
@@ -10,6 +10,7 @@ bin/
# Frontend
web/node_modules/
web/dist/
web/.storybook-static/
# Test binary, built with `go test -c`
*.test
+20 -17
View File
@@ -1,25 +1,28 @@
// Copyright 2026 certctl LLC. All rights reserved.
// SPDX-License-Identifier: BUSL-1.1
//
// Phase 8 TEST-H3 closure — Storybook configuration scaffold.
// Phase 8 TEST-H3 closure — Storybook configuration. Fully wired
// 2026-05-14 via Storybook 10.
//
// DEPS NOT INSTALLED IN PACKAGE.JSON. The first attempt added
// `@storybook/react-vite ^8.6.0` + `@storybook/addon-a11y ^8.6.0`
// + `storybook ^8.6.0` to package.json, but Storybook 8's peerDeps
// cap Vite at v6 — the certctl project ships Vite 8 (Phase 4
// manualChunks rewrite). CI fail confirmed the peer-conflict via
// `npm ci`. Hotfix #9 removed the deps to unblock CI.
// Version-selection history (recorded so the next operator who
// upgrades Vite doesn't re-walk the same wall):
// • Phase 8 first attempt: Storybook 8.6 — peer-capped at Vite 6,
// project shipped Vite 8 (Phase 4 manualChunks rewrite). CI's
// `npm ci` failed ERESOLVE; Hotfix #9 removed the deps.
// • This file's earlier header speculated "Storybook 9 supports
// Vite 7+8" — that was wrong. Verified at install time
// 2026-05-14: Storybook 9.1.20's peer range is Vite 5/6/7,
// ERESOLVE'd again.
// • Storybook 10.4.0 is the first version with explicit Vite 8
// in the peer range (^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0).
// Installed cleanly. All 8 *.stories.tsx files typecheck +
// `storybook build` succeeds (~3s, 17 chunks emitted).
//
// To install:
// cd web && npm install --save-dev storybook@^9.0.0 \
// @storybook/react-vite@^9.0.0 @storybook/addon-a11y@^9.0.0
// # Storybook 9 supports Vite 7+8 — verified against storybook.js.org
// # docs before installing.
//
// Once installed, this main.ts + preview.ts work as-is. The 8
// committed *.stories.tsx files import @storybook/react types and
// will typecheck cleanly. tsconfig.json excludes them today so
// `npm run build` stays green in the meantime.
// tsconfig.json no longer excludes *.stories.tsx — Storybook 10's
// @storybook/react types are correct and the existing story files
// validate against them. `npm run build` is unchanged (Vite still
// only emits the production bundle; stories live in a separate
// `npm run storybook:build` script).
//
// Reuses the existing Vite config from web/vite.config.ts
// (including the Phase 4 manualChunks, the Phase 0 fontsource
+2411
View File
File diff suppressed because it is too large Load Diff
+6 -1
View File
@@ -11,7 +11,9 @@
"test:watch": "vitest",
"e2e": "playwright test",
"e2e:install": "playwright install --with-deps chromium",
"generate": "orval --config ./orval.config.ts"
"generate": "orval --config ./orval.config.ts",
"storybook": "storybook dev -p 6006",
"storybook:build": "storybook build --output-dir=.storybook-static"
},
"dependencies": {
"@floating-ui/react": "^0.27.19",
@@ -33,6 +35,8 @@
"devDependencies": {
"@axe-core/react": "^4.11.3",
"@playwright/test": "^1.49.0",
"@storybook/addon-a11y": "^10.4.0",
"@storybook/react-vite": "^10.4.0",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@types/jest-axe": "^3.5.9",
@@ -44,6 +48,7 @@
"jsdom": "^29.0.0",
"orval": "^7.0.0",
"postcss": "^8.5.8",
"storybook": "^10.4.0",
"tailwindcss": "^3.4.19",
"typescript": "^5.9.3",
"vite": "^8.0.10",
+4 -4
View File
@@ -16,28 +16,28 @@ type Story = StoryObj<typeof meta>;
export const Error: Story = {
args: {
severity: 'error',
type: 'error',
children: 'Failed to issue certificate — CA rejected the CSR (RFC 5280 §4.2.1.6 SAN violation).',
},
};
export const Warning: Story = {
args: {
severity: 'warning',
type: 'warning',
children: 'This issuer is in maintenance mode — new issuance requests will queue.',
},
};
export const Success: Story = {
args: {
severity: 'success',
type: 'success',
children: 'Renewal complete. New certificate deployed to 3 targets.',
},
};
export const Info: Story = {
args: {
severity: 'info',
type: 'info',
children: 'Approval requested. Awaiting sign-off from a different operator.',
},
};
-2
View File
@@ -20,8 +20,6 @@
},
"include": ["src"],
"exclude": [
"src/**/*.stories.tsx",
"src/**/*.stories.ts",
"src/__tests__/e2e/**/*.spec.ts"
]
}