portfolio

Quality

Gates

pnpm lint          # ESLint, including jsx-a11y
pnpm typecheck     # tsc --noEmit
pnpm test          # Vitest
pnpm test:coverage # Vitest with thresholds
pnpm format:check  # Prettier
pnpm build         # Next static export
pnpm security:audit

pnpm check runs lint, typecheck, tests and build in sequence.

CI

.github/workflows/ci.yml is a reusable workflow with three gating jobs:

.github/workflows/pages.yml calls the whole workflow as a prerequisite of build, so any failing gate stops the deploy rather than being reported afterwards.

The dependency audit is a gating job. It checks the public site, the panel UI’s separate lockfile, and the pinned Python requirements; a moderate-or-higher advisory blocks deployment.

What is actually covered

Site. Coverage is scoped to src/content and src/lib — the pure logic and the content contracts — with 80% thresholds. There are still no component or end-to-end tests: rendering is not covered, and the build failing on a type or schema error is what catches most breakage. Stating this plainly because an untested claim is worse than an absent one.

Control panel. admin/content/tests.py covers the API: who can read what, that a wrong password and an unknown user are indistinguishable, that nested writes replace child collections in one transaction and leave existing rows untouched when validation rejects, that the export excludes drafts and matches the shape the site parses, and that the project list stays ordered by position. That last test exists because the ordering regressed once and returned 200 while doing nothing visible.

Panel UI. Type checked and built in CI; no component tests.

The content tests are the interesting ones. Beyond slug uniqueness and safe external links, src/content/content.test.ts enforces the editorial rules of the site:

That last one exists because this repository previously shipped placeholder GitHub links and a placeholder email address to production.

Next, in priority order

  1. Playwright smoke tests for route rendering, mobile navigation and the theme toggle.
  2. Component tests for FilterableProjectGrid and ThemeToggle, the only two pieces of real client-side state.
  3. Lighthouse or an equivalent budget in CI, once the flagship infrastructure work lands.

Performance notes