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>
2.6 KiB
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 errorspnpm --filter @mintel/web test— unit specs (Vitest); 0 tests run counts as a failurepnpm --filter @mintel/web test:coverage—src/domainmust stay at 100%pnpm --filter @mintel/web test:mutation— Stryker onsrc/domain, ~2 min, must score 100pnpm --filter @mintel/web lint
How to work here (spec first)
- Write the behavior as concrete cases (inputs, outputs, edge cases, errors) as a
*.spec.ts. - Run it and confirm it fails for the right reason (missing behavior, not an import error).
- Implement the simplest clean solution, run again.
- Run typecheck, coverage and mutation. Survivors mean weak specs or dead code: fix one or the other.
- 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; passtodayetc. 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 tomain, or runreset --hard,clean,rm -rfwithout asking. - Edit
.gitea/workflows/*or deploy config without asking. - Upgrade
vitestpast 4.1.x:@stryker-mutator/vitest-runner10.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
pluginslisted explicitly instryker.config.json(pnpm layout) and ignores the large asset folders viaignorePatterns; keep them in sync when adding top-level folders. @mintel/*packages arelink:dependencies on a siblingat-mintelcheckout.- Git branches: work on
feat/*, never directly onmain.