Skip to content

refactor(nav): portal paths were written down 38 times; now once - #72

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

refactor(nav): portal paths were written down 38 times; now once#72
github-actions[bot] merged 1 commit into
mainfrom
refactor/portal-routes-ssot

Conversation

@catomean

Copy link
Copy Markdown
Collaborator

/portal/dashboard and /portal/find were each hand-typed six times in SidebarNav.tsx alone — 38 occurrences of thirteen paths across the portal components, plus /portal/pets/\${petId}/health/log templated in two files.

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

lib/config/routes.ts is now the one place: static paths as a const object, plus petPath() / petHealthLogPath() for the two that need an id. A template literal in a component is a copy like any other.

The guard is the point

routes.test.ts scans components/portal for a quoted /portal/ literal and fails on one, so this can't quietly come back.

It was stricter than my first pass at the fix — it caught QuickActions.tsx and both dynamic paths that a file-by-file sweep had missed. That's exactly the job, and it's the reason the test exists rather than just the constants.

Recorded in CLAUDE.md's SSOT table and Red Flags list, so the rule is findable without reading this commit.

Verification

No behaviour change — every path resolves to the same string it did before. Typecheck clean, lint clean, 904 tests pass (88 files).

Found by a fleet-wide navigation audit across 20 repos, where petvity had the highest concentration of hand-typed destinations in a single file.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XeELB8b3N4JrT2asYL9WvE

`/portal/dashboard` and `/portal/find` were each hand-typed six times in
SidebarNav.tsx alone — 38 occurrences of thirteen paths across the portal
components, plus `/portal/pets/${petId}/health/log` templated in two files.
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.

lib/config/routes.ts is now the one place. Static paths as a const object,
and functions for the two that need an id — a template literal in a component
is a copy like any other.

The guard is the point. routes.test.ts scans components/portal for a quoted
/portal/ literal and fails on one, so this cannot quietly come back. It is
stricter than the first pass of the fix was: it caught QuickActions.tsx and
both dynamic paths that a file-by-file sweep had missed, which is exactly the
job. Recorded in CLAUDE.md's SSOT table and Red Flags list so the rule is
findable without reading this commit.

No behaviour change: every path resolves to the same string it did before.
Typecheck clean, lint clean, 904 tests pass.

Found by a fleet-wide navigation audit across 20 repos, where petvity had the
highest concentration of hand-typed destinations in a single file.

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 4133ee1 into main Aug 31, 2026
1 check passed
@github-actions
github-actions Bot deleted the refactor/portal-routes-ssot branch August 31, 2026 07:56
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