Files
mintel.me/CLAUDE.md
T
mmintelandClaude Sonnet 5.5 d33a5d6c63 chore: enable TypeScript strict mode and drop dead Payload scripts
The shared base tsconfig had strict off, so null-safety and union narrowing
were not checked. Strict is now on for apps/web with 5 small typing fixes.
check-db.ts and migrate-drafts.js depended on Payload, which is no longer a
dependency, and are removed. CLAUDE.md no longer claims Payload.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-03 18:59:47 +02:00

2.6 KiB

mintel.me

Personal website of a senior freelance engineer. Next.js 16 (App Router), pnpm monorepo. App lives in apps/web. Concept and scope: apps/web/plans/freelance-relaunch.md (read it first).

Commands (run from repo root)

  • pnpm --filter @mintel/web typecheck — must pass with zero errors
  • pnpm --filter @mintel/web test — unit specs (Vitest); 0 tests run counts as a failure
  • pnpm --filter @mintel/web test:coverage — src/domain must stay at 100%
  • pnpm --filter @mintel/web test:mutation — Stryker on src/domain, ~2 min, must score 100
  • pnpm --filter @mintel/web lint

How to work here (spec first)

  1. Write the behavior as concrete cases (inputs, outputs, edge cases, errors) as a *.spec.ts.
  2. Run it and confirm it fails for the right reason (missing behavior, not an import error).
  3. Implement the simplest clean solution, run again.
  4. Run typecheck, coverage and mutation. Survivors mean weak specs or dead code: fix one or the other.
  5. Report the exact commands and results. "Done" means they were run on the current code. Never weaken, skip or delete a test to make it pass.

Architecture rules

  • Functional core, imperative shell. Pure logic goes in apps/web/src/domain/ (no I/O, no clock, no randomness, no framework imports; pass today etc. in as arguments). Everything there is covered 100% and mutation-tested. Pages, routes and adapters stay thin and call into the core.
  • Parse at the boundary into precise types (Result, discriminated unions); no nullable state bags.
  • No any, @ts-ignore, ! non-null assertions or eslint-disable to silence errors. Fix the cause.

Do not

  • Read or edit .env* (only .env.example). Never print or log secrets.
  • Commit scratch files (tmp*, *.log, *.tmp, debug HTML, build output). They are gitignored; keep it so.
  • Use --no-verify, force-push, push to main, or run reset --hard, clean, rm -rf without asking.
  • Edit .gitea/workflows/* or deploy config without asking.
  • Upgrade vitest past 4.1.x: @stryker-mutator/vitest-runner 10.0.0 runs zero tests per mutant under vitest 5 and reports false survivors. Re-verify mutation results after any tooling bump.
  • Add dependencies for trivial things, or touch unrelated code (no drive-by refactors).

Gotchas

  • Stryker needs plugins listed explicitly in stryker.config.json (pnpm layout) and ignores the large asset folders via ignorePatterns; keep them in sync when adding top-level folders.
  • @mintel/* packages are link: dependencies on a sibling at-mintel checkout.
  • Git branches: work on feat/*, never directly on main.