refactor(nav): internal routes were written down 40 times; now once - #234
Merged
Conversation
`/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
catomean
force-pushed
the
refactor/nav-ssot
branch
from
August 31, 2026 08:24
12d7787 to
1434ba1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
/builderwas hand-typed in ten places across six files,/erfassungin eight,/formsin 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.tsis now the one place, plusblogPostPath()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.tswalksfrontend/srcand fails on a quoted literal of any routeROUTESowns, naming the file, line and text.Mutation-proven by reverting one usage in
fyi/page.tsx: the suite fails and points atapp/fyi/page.tsx:64with the offending line.Deliberately NOT included
TopNavigationrenders its mobile menu from anavigationarray 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
.contentlayer/generated, exactly asCLAUDE.mddocuments. Identical count before and after this change;npx contentlayer buildclears them.)npm run build: green, including the/blog/[slug]prerender thatCLAUDE.mdrecords 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