Skip to content

refactor: collapse App.js's 5-way route-path duplication into one ROUTES constant - #386

Merged
michaelrobertsutton merged 1 commit into
mainfrom
chore/routes-single-source
Jul 30, 2026
Merged

refactor: collapse App.js's 5-way route-path duplication into one ROUTES constant#386
michaelrobertsutton merged 1 commit into
mainfrom
chore/routes-single-source

Conversation

@michaelrobertsutton

Copy link
Copy Markdown
Collaborator

Summary

  • frontend/src/App.js spelled out the same route paths in five separate places (<Route> JSX, ALL_NAV_ITEMS, PAGE_TITLE, SEARCH_PLACEHOLDER, plus serve.json in a different file) with nothing keeping them in sync — that gap is what caused bug: /groups route 404s on direct navigation (missing serve.json rewrite) #383 (/groups added to the JSX and nav but never to serve.json, so direct navigation 404'd).
  • New frontend/src/routes.js exports one ROUTES array; App.js now derives its <Route> table, sidebar nav, keyboard shortcuts, header title, and search placeholder from it instead of hand-maintaining six parallel lists (a sixth duplication site — the keyboard-shortcut if/else chain — was found and collapsed too).
  • App.routes.test.js (added by fix: add missing /groups serve.json rewrite causing direct-nav 404 #385 as an interim regex-over-source guard) is rewritten to validate the real ROUTES data against serve.json structurally, and now also asserts no hand-written <Route path="..."> can bypass ROUTES in the first place (any literal-path spelling — double/single-quoted or {...}-wrapped) — closing the exact bypass bug: /groups route 404s on direct navigation (missing serve.json rewrite) #383 exploited.
  • Pure refactor — no behavior change intended, and none found in review or testing.

Related issue

Closes #384

Type of change

  • Refactor / cleanup

Checklist

  • Tests added or updated — rewrote App.routes.test.js as a structural guard, added App.test.js render smoke test
  • docs/ updated (if architecture or API changed) — N/A, no architecture change
  • No new ADRs needed, OR I've added an entry to docs/decisions.md
  • Security implications considered (N/A for pure refactor/docs)

Test plan

  • cd frontend && npm test -- --watchAll=false — 8 suites / 99 tests passing (up from 92 on baseline main)
  • cd frontend && npm run build — compiles cleanly, output 388B smaller gzipped
  • cd backend && python3 -m pytest tests/ --ignore=tests/integration -v — 503 passed (unaffected by this change, run to confirm)
  • ./scripts/run-integration-tests.sh (CI-equivalent flags) — 33 passed, 3 skipped, 0 failed
  • Full production-path browser smoke walk against the local Docker stack (docker compose up -d --build, exercising the actual serve binary + serve.json): hard navigation to /, /measures, /jobs, /groups, /results, /results/:jobId, /validation, /settings all load the app shell (not a 404) with correct header title, search placeholder, and sidebar order; feature-flag gating (Groups/Validation nav visibility) and keyboard shortcuts (M/J/E navigate, G/V suppressed when flags off, all suppressed while the search box is focused) verified
  • Independent /codex review — found two real gaps (bypass-guard regex missed single-quoted/expression-literal paths; kbd-uniqueness check wasn't case-normalized to match App.js's case-insensitive matching) — both fixed and re-verified

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01QCHg8DX1rzgPDCm5CsHF7g

App.js spelled out the same route paths in five separate places (Route
JSX, nav items, page titles, search placeholders, serve.json) with
nothing keeping them in sync -- the exact gap that caused #383. Now
frontend/src/routes.js is the single source of truth that App.js
derives its Route table, sidebar nav, keyboard shortcuts, header
title, and search placeholder from, and App.routes.test.js validates
that data against serve.json structurally instead of regex-scraping
App.js's source.

Closes #384

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCHg8DX1rzgPDCm5CsHF7g
@michaelrobertsutton
michaelrobertsutton merged commit 0a2a341 into main Jul 30, 2026
6 checks passed
@michaelrobertsutton
michaelrobertsutton deleted the chore/routes-single-source branch July 30, 2026 20:05
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.

refactor: collapse App.js's 5-way route-path duplication into one ROUTES constant

1 participant