Skip to content

chore(tooling): modernize the toolchain and fix pre-existing bugs - #17

Merged
arnaud-zg merged 5 commits into
mainfrom
fix/domain-red-suite-and-dead-repo
Sep 2, 2026
Merged

arnaud-zg merged 5 commits into
mainfrom
fix/domain-red-suite-and-dead-repo

Conversation

@arnaud-zg

@arnaud-zg arnaud-zg commented Sep 2, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • moved from Bun to pnpm, adopted @arnaud-zg/configs (tsconfig variants, commitlint,
    remark, a Biome v2 upgrade), Lefthook pre-commit hooks, dropped the unused ESLint config
  • CI now runs typecheck, Biome, markdown lint and tests on every push, and pushes to
    main auto-deploy to GitHub Pages instead of a manual gh-pages run
  • every magic number (base path, tax rate, shipping threshold, analytics id) moved into
    src/config/*.config.ts, isolated from the code that uses it
  • fixed four real, pre-existing bugs found along the way: ShippingPolicy.spec.ts was
    asserting a threshold and cost the policy no longer used (four failing tests), a
    committed empty spec file was silently reporting "no tests found", zod was used by
    three files without being a declared dependency, and
    LocalStorageWelcomeSurveyRepository.getSurvey() could never actually read from
    storage because of a cache check that always won
flowchart LR
  A[Bun scaffold, ESLint, manual deploy] --> B[pnpm, shared configs, CI, auto deploy]
  C[4 pre-existing bugs] --> D[fixed, regression-tested]
Loading

Test plan

  • pnpm typecheck
  • pnpm check
  • pnpm lint:md
  • pnpm test
  • pnpm build

🤖 Generated with Claude Code

https://claude.ai/code/session_014BcGPRc3sgUJYKihGRXh5g

arnaud-zg and others added 5 commits September 1, 2026 23:04
- pnpm is now the package manager (pnpm-lock.yaml, engines, .nvmrc), Bun stays supported
  as a runtime for local dev
- delete eslint.config.js, Biome is the only linter/formatter, bumped to 2.5.11
- widen Biome's file glob from src/* to the whole repo, it silently skipped every nested
  file before (src/lib/utils.ts had never actually been formatted)
- adopt @arnaud-zg/configs: tsconfig variants, commitlint (scope is now mandatory),
  remark for markdown linting
- hand-write lefthook.yml instead of extending the shared one, it hardcodes Prettier and
  this repo uses Biome
- add zod as a direct dependency, pnpm's strict node_modules stopped hoisting it in
  through @shadcn/ui
- typecheck now runs before vite build instead of after

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014BcGPRc3sgUJYKihGRXh5g
- bump Vite to 8, Vitest to 4, jsdom to 30, @vitejs/plugin-react to 6, TanStack Store to
  0.11, all runtime deps to their latest within existing ranges
- rename framer-motion to motion (12 -> 13), import site moves to "motion/react"
- bump lucide-react to 1.x, it dropped the brand icons: Github/Linkedin now come from
  @radix-ui/react-icons instead, already a dependency
- @tanstack/store 0.11's Store.subscribe() now returns a Subscription object instead of
  a bare unsubscribe function, adjusted the one repository that calls it
- remove @shadcn/ui, a stub package that was never imported
- hold TypeScript at 5.9, a jump to 7 is out of scope for a demo repo

jsdom 30 requires Node >=22.22.2, bumped local dev Node accordingly; CI resolves Node from
.nvmrc so it already gets a current 22.x.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014BcGPRc3sgUJYKihGRXh5g
- CI workflow: pnpm install, typecheck, biome check, markdown lint, test, build, on
  every push to main and every pull request
- Deploy workflow: builds and pushes dist to the gh-pages branch on push to main, keeps
  the existing GitHub Pages source instead of switching it to Actions
- dependabot for npm (weekly, grouped) and github-actions
- add the MIT LICENSE the package.json already claimed, and a PR template matching this
  stack's Summary / Test plan shape

The Test step will be red until the domain fixes later in the stack land, that failure is
pre-existing and already called out in earlier PRs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014BcGPRc3sgUJYKihGRXh5g
- src/config/site.config.ts: base path, canonical origin, author and social links, the
  article link, shared by vite.config.ts (build) and main.tsx (runtime)
- src/config/commerce.config.ts: tax rate, free shipping threshold and cost, per-item
  quantity limits, currency conversion factors. ShippingPolicy, TaxPolicy, CartItem, and
  GoldSilverCopperFormatter read from it instead of hardcoding numbers, and their static
  fields are now readonly
- src/config/storage.config.ts: which WelcomeSurveyStorage implementation is active,
  replacing three commented-out imports in a UI file with one line in a config file
- src/config/analytics.config.ts: the Umami event-name taxonomy, replacing scattered
  string literals across ShoppingCart.tsx, WelcomeModal.tsx, and the home route
- the Umami website id now lives in .env (VITE_UMAMI_WEBSITE_ID) and is interpolated into
  index.html's script tag and read by analytics.config.ts, one source of truth for both
- public/404.html can't import a TS module, added a comment pointing at site.config.ts as
  the source it has to stay in sync with

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014BcGPRc3sgUJYKihGRXh5g
- ShippingPolicy.spec.ts asserted a 50/5.99 threshold that stopped matching the real
  300/25 constants a while ago (4 failing tests). Rewrote it to read the expected values
  off ShippingPolicy's own constants instead of duplicating them, so it can't go stale
  the same way again
- delete the empty, committed value-objects/__spec__/Product.spec.ts, superseded by the
  one under value-objects/Product/
- Product.spec.ts gave beginner/adventurer/expert the exact same ProfileDetails, so the
  level-routing logic was never actually exercised. Gave each level distinct data,
  which is what caught Product.getLoreLink/getVideoUrl having three branches that all
  returned the same expression
- LocalStorageWelcomeSurveyRepository.getSurvey() could never read localStorage: cache
  was initialized to {survey: null}, so the `cache !== undefined` guard always won.
  Fixed the sentinel and added the coverage this repository never had
- TanstackStoreWelcomeSurvey.repository.ts touched localStorage at import time with no
  guard, which would crash under a Node server-side render (the prerender step lands
  later in this stack). Guarded both accesses, added a node-environment spec proving the
  module now imports and works without a DOM

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014BcGPRc3sgUJYKihGRXh5g
@arnaud-zg arnaud-zg changed the title TEST: consolidated toolchain PR chore(tooling): modernize the toolchain and fix pre-existing bugs Sep 2, 2026
@arnaud-zg arnaud-zg self-assigned this Sep 2, 2026
@arnaud-zg arnaud-zg added the enhancement New feature or request label Sep 2, 2026
@arnaud-zg arnaud-zg closed this Sep 2, 2026
@arnaud-zg
arnaud-zg deleted the fix/domain-red-suite-and-dead-repo branch September 2, 2026 19:01
@arnaud-zg
arnaud-zg restored the fix/domain-red-suite-and-dead-repo branch September 2, 2026 19:13
@arnaud-zg arnaud-zg reopened this Sep 2, 2026
@arnaud-zg
arnaud-zg merged commit 91944ed into main Sep 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant