Problem
frontend/src/app.ts is well past the 500-line ceiling stated in CLAUDE.md
("Keep files under 500 lines"), and the mobile navigation / header projection
behaviour is the largest self-contained chunk in it.
Line counts:
The violation predates PR LeanerCloud/cloud-commitments-cli#1877. At 802 lines the file was already 60%
over the ceiling. PR LeanerCloud/cloud-commitments-cli#1877 added 81 lines to it: 63 in the fix for LeanerCloud/cloud-commitments-cli#1779 plus
18 in the accessibility follow-up on the widening path.
CodeRabbit raised the extraction on PR LeanerCloud/cloud-commitments-cli#1877 and it was declined there on
scope grounds: it is a restructuring of a file shared by most of the frontend,
unrelated to the p1 bug that PR fixes, and bundling it would have both blown
the PR's blast radius and buried the actual fix.
Proposal
Move the mobile-nav and header-projection behaviour out of app.ts into its
own bounded-context module (for example frontend/src/nav/mobile-nav.ts)
exposing a typed public API rather than loose exported functions.
Symbols to move (all currently in frontend/src/app.ts):
MOBILE_NAV_QUERY, the (max-width: 768px) breakpoint constant
DRAWER_PROJECTED_IDS
syncHeaderPlacement(isNarrow: boolean)
setupMobileNav() and its inner openDrawer / closeDrawer /
releaseDrawerForDesktop transitions
Blast radius
Small, which is what makes this worth doing as its own change:
frontend/src/__tests__/mobile-nav.test.ts is the only importer
(import { setupMobileNav, syncHeaderPlacement } from '../app'). The jest
coverage already lives in its own file, so the test move is a re-point of
one import.
frontend/tests-e2e/mobile-header-drawer.spec.ts drives the behaviour
through the browser and needs no change.
- Three comments name the current home and should be updated in the same
change: frontend/src/index.html (the #sidebar-extras slot),
frontend/src/styles/responsive.css lines 76 and 178.
Acceptance
frontend/src/app.ts drops below 500 lines, or the remaining excess is
identified as a separate follow-up with its own extraction target.
- The new module exports a typed API; no behaviour change.
npm test, npm run lint, tsc --noEmit and the full Playwright suite
stay green, with the mobile-nav jest and e2e coverage unchanged in substance.
Problem
frontend/src/app.tsis well past the 500-line ceiling stated inCLAUDE.md("Keep files under 500 lines"), and the mobile navigation / header projection
behaviour is the largest self-contained chunk in it.
Line counts:
frontend/src/app.tsb83c5d14e)The violation predates PR LeanerCloud/cloud-commitments-cli#1877. At 802 lines the file was already 60%
over the ceiling. PR LeanerCloud/cloud-commitments-cli#1877 added 81 lines to it: 63 in the fix for LeanerCloud/cloud-commitments-cli#1779 plus
18 in the accessibility follow-up on the widening path.
CodeRabbit raised the extraction on PR LeanerCloud/cloud-commitments-cli#1877 and it was declined there on
scope grounds: it is a restructuring of a file shared by most of the frontend,
unrelated to the p1 bug that PR fixes, and bundling it would have both blown
the PR's blast radius and buried the actual fix.
Proposal
Move the mobile-nav and header-projection behaviour out of
app.tsinto itsown bounded-context module (for example
frontend/src/nav/mobile-nav.ts)exposing a typed public API rather than loose exported functions.
Symbols to move (all currently in
frontend/src/app.ts):MOBILE_NAV_QUERY, the(max-width: 768px)breakpoint constantDRAWER_PROJECTED_IDSsyncHeaderPlacement(isNarrow: boolean)setupMobileNav()and its inneropenDrawer/closeDrawer/releaseDrawerForDesktoptransitionsBlast radius
Small, which is what makes this worth doing as its own change:
frontend/src/__tests__/mobile-nav.test.tsis the only importer(
import { setupMobileNav, syncHeaderPlacement } from '../app'). The jestcoverage already lives in its own file, so the test move is a re-point of
one import.
frontend/tests-e2e/mobile-header-drawer.spec.tsdrives the behaviourthrough the browser and needs no change.
change:
frontend/src/index.html(the#sidebar-extrasslot),frontend/src/styles/responsive.csslines 76 and 178.Acceptance
frontend/src/app.tsdrops below 500 lines, or the remaining excess isidentified as a separate follow-up with its own extraction target.
npm test,npm run lint,tsc --noEmitand the full Playwright suitestay green, with the mobile-nav jest and e2e coverage unchanged in substance.