What this domain owns
How a learner moves between product screens. It does not own lesson rules or progress calculations.
Feature flow diagram
Link or browser history
│ hashchange
v
app-route.ts ──parse──> AppRoute
│
v
app-shell.tsx ──selects──> screen component
│ │
└── navigation / scroll / analyticsThis diagram shows the normal direction of control and data. Follow it before changing a boundary or adding a dependency.
Class and relationship diagram
┌───────────────┐ parse(raw) ┌─────────────────────────┐
│ AppRoute │◀───────────────────│ RouteParser │
├───────────────┤ ├─────────────────────────┤
│ + screen │ │ + parseAppRoute() │
│ + segments │ │ + activeNavigation() │
│ + params │ └───────────┬─────────────┘
└───────┬───────┘ │ selects
▼ ▼
┌──────────────────────────┐ ┌────────────────────────┐
│ AppShell │ │ Screen component │
├──────────────────────────┤ ├────────────────────────┤
│ + session │ │ + receives route/state │
│ + learner state │ │ + renders one screen │
│ + renderRoute() │ └────────────────────────┘
└──────────────────────────┘Boxes show the important data types or services. Their fields and main methods are listed inside; arrows show the primary dependency or data relationship.
Sequence diagram
Read this from top to bottom: each arrow is the next interaction in the normal successful path.
Start here in the code
Choose any filename to open it directly in VS Code.
How it works
- A hash changes.
- The route parser creates a screen and parameters.
- App shell selects one screen component.
- Navigation, access checks, analytics, and scroll restoration run around that screen.
Read this code
components/app/app-route.tsOpen in VS Code — Turn a URL hash into a screen request
export function parseAppRoute(raw: string): AppRoute {
const [path = '', query = ''] = raw.split('?', 2);
const segments = path.split('/').filter(Boolean);
const candidate = segments[0] ?? 'today';
const screen = (knownScreens.has(candidate) ? candidate : 'today') as AppScreen;
return { screen, params: new URLSearchParams(query), /* … */ };
}What each part is doing
- The browser supplies the part after # as raw.
- Unknown screens safely fall back to today instead of rendering an invalid page.
- The app shell uses screen to select the page component; add a screen to the allow-list before routing to it.
This is a deliberately short excerpt of the real pattern, with unrelated details omitted. Read the named file for the complete implementation.
Related API and server boundaries
- Mostly client-side. See /api/auth/session for session refresh and /api/events for route analytics.
Tests to read and run
Implementation notes
This is the home for detailed explanations, decision records, request examples, and diagrams for this feature. Add new feature-specific documentation here instead of expanding the platform overview.