Skip to content

refactor(nav): internal routes were written down 40 times; now once - #234

Merged
github-actions[bot] merged 1 commit into
mainfrom
refactor/nav-ssot
Aug 31, 2026
Merged

refactor(nav): internal routes were written down 40 times; now once#234
github-actions[bot] merged 1 commit into
mainfrom
refactor/nav-ssot

Conversation

@catomean

Copy link
Copy Markdown
Collaborator

/builder was hand-typed in ten places across six files, /erfassung in eight, /forms in seven. Renaming a route meant finding every copy, and a missed one did not fail to compile — it became a dead link only a visitor would discover.

The fix

frontend/src/lib/routes.ts is now the one place, plus blogPostPath() for the one templated path — a template literal in a component is a copy like any other. 14 files converted.

No behaviour change: every path resolves to the same string it did before.

The guard

routes.test.ts walks frontend/src and fails on a quoted literal of any route ROUTES owns, naming the file, line and text.

Mutation-proven by reverting one usage in fyi/page.tsx: the suite fails and points at app/fyi/page.tsx:64 with the offending line.

Deliberately NOT included

TopNavigation renders its mobile menu from a navigation array while its desktop links are inline JSX — so the two menus can still disagree about what the site contains. That's the deeper defect the audit found here.

Unifying them changes what the nav shows, which is a design decision and doesn't belong inside a rename-safety refactor. Filing it as a follow-up rather than silently folding it in.

Verification

  • Typecheck: 0 errors. (A fresh worktree shows 7 — all missing .contentlayer/generated, exactly as CLAUDE.md documents. Identical count before and after this change; npx contentlayer build clears them.)
  • Lint: 0 errors (161 pre-existing warnings, untouched).
  • Tests: 46 pass.
  • npm run build: green, including the /blog/[slug] prerender that CLAUDE.md records as the thing only a build catches.

Found by a fleet-wide navigation audit across 20 repos.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XeELB8b3N4JrT2asYL9WvE

`/builder` was hand-typed in ten places across six files, `/erfassung` in
eight, `/forms` in seven. Renaming a route meant finding every copy, and a
missed one did not fail to compile: it became a dead link only a visitor would
discover.

frontend/src/lib/routes.ts is now the one place, plus blogPostPath() for the
one templated path — a template literal in a component is a copy like any
other. 14 files converted, no behaviour change: every path resolves to the
same string it did before.

routes.test.ts is the part that lasts. It walks frontend/src and fails on a
quoted literal of any route ROUTES owns, naming the file, line and text.
Mutation-proven by reverting one usage in fyi/page.tsx: the suite fails and
points at `app/fyi/page.tsx:64`.

Deliberately NOT included: TopNavigation renders its mobile menu from a
`navigation` array while its desktop links are inline JSX, so the two menus can
still disagree about what the site contains. Unifying them changes what the nav
shows, which is a design decision and does not belong inside a rename-safety
refactor. Filed as follow-up, not silently folded in.

Typecheck clean (0 errors once contentlayer types are generated — the 7 seen in
a fresh worktree are missing codegen, identical before and after this change).
Lint 0 errors. 46 tests pass.

Found by a fleet-wide navigation audit across 20 repos.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeELB8b3N4JrT2asYL9WvE
@github-actions
github-actions Bot merged commit c426c0e into main Aug 31, 2026
1 check passed
@github-actions
github-actions Bot deleted the refactor/nav-ssot branch August 31, 2026 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant