Define named route constants and route metadata schema
epic-navigation-and-gesture-accessibility-foundation-task-004 — Define all named route constants (route names, paths) for the five tab branches and their sub-routes in a central route-constants file. Define a RouteMetadata model that carries accessibility label, suppressSwipeBack flag, and semanticsIdentifier. This file becomes the single source of truth for all route names referenced by GoRouter and by the accessibility service.
Acceptance Criteria
Technical Requirements
Implementation Notes
Keep this file purely declarative — no logic, no providers, no imports beyond `package:flutter/foundation.dart` for `@immutable`. Use a `const` constructor on `RouteMetadata`. Consider a `RouteMetadata.defaults({required String semanticsLabel, required String semanticsIdentifier})` factory that sets `suppressSwipeBack: true` by default, since the accessibility requirement states swipe-back must be suppressed on ALL routes. Group constants by tab branch using static nested classes or a clear comment section for readability (e.g., `// --- Home branch ---`).
The `semanticsIdentifier` values will be consumed by automated accessibility audit tooling, so they must be stable — never change them once assigned. Use reverse-DNS style identifiers such as `no.norskhandikapforbund.home.root` for forward compatibility.
Testing Requirements
Unit tests in `test/navigation/route_constants_test.dart`: (1) Verify all five tab root constants are non-empty and unique strings. (2) Verify `RouteMetadata` equality semantics — two instances with identical fields must be equal. (3) Verify `RouteMetadata.suppressSwipeBack` defaults to `true` if a convenience constructor is provided. (4) Verify `semanticsLabel` values do not contain underscores or camelCase (should be natural language).
(5) Verify `semanticsIdentifier` values match a defined naming convention (e.g., snake_case). Target: 100% branch coverage for the `RouteMetadata` class.
StatefulShellRoute branch navigator state can interact unexpectedly with GoRouter's imperative navigation (go, push, replace), causing state snapshots to desync from actual route stacks. This could manifest as a user returning to a tab and seeing a different screen than expected, breaking the core motor-fatigue promise.
Mitigation & Contingency
Mitigation: Write integration tests that simulate cross-tab navigation with nested pushes before any UI layer is built. Pin go_router to a tested minor version and review the StatefulShellRoute changelog before upgrading.
Contingency: If branch navigator state consistently desyncs, fall back to a manual stack snapshot strategy using a custom NavigatorObserver that records and replays navigation events independently of StatefulShellRoute internals.
Persisted navigation stacks in shared_preferences can become stale or corrupt if route paths are renamed during development, causing app crashes or infinite redirect loops on cold start for users who have an old snapshot.
Mitigation & Contingency
Mitigation: Version the persisted schema with a format key. On app start, validate that all stored route paths exist in the current route config before restoring; silently discard invalid entries rather than crashing.
Contingency: Implement a safe-mode cold start that skips state restoration after a detected crash (via a dirty-launch flag written at startup and cleared on successful first frame), falling back to the default root tab.