Implement role-based post-login routing in LoginScreen
epic-email-password-login-ui-task-010 — On successful authentication, LoginScreen must route the user to their role-specific home screen. Read the session result from LoginFormBLoC success state, resolve the user role (coordinator, peer_mentor, org_admin), and push the corresponding named route using GoRouter. Ensure no intermediate flicker and that navigation stack is replaced so back button does not return to login.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 7 - 84 tasks
Can start after Tier 6 completes
Implementation Notes
Use BlocListener (not BlocBuilder) for navigation side effects — this ensures navigation fires exactly once as a side effect of state change, not on every rebuild. Define a _navigateForRole(BuildContext context, UserRole role) private method in LoginScreen that calls context.go(RouteNames.forRole(role)). The RouteNames.forRole() mapping should live in a central router constants file, not inline. Extract role from the LoginSuccess state's AuthSession.user.userMetadata['role'] field (set by Supabase on sign-in).
Guard against null/missing role by defaulting to the no-access route. For deep-link support, store any pending redirect in GoRouter's redirect logic using a notifier pattern — the redirect resolves after auth state changes. The StatefulShellRoute used for tab navigation should only be entered after role is confirmed — do not enter it and then check role inside.
Testing Requirements
Widget/integration tests (flutter_test): (1) Mock BLoC emits LoginSuccess with coordinator role → verify GoRouter navigated to coordinator-home route; (2) peer_mentor role → peer-mentor-home route; (3) org_admin role → org-admin-home route; (4) unknown role → no-access route; (5) verify LoginScreen is not in the navigation stack after success (use GoRouter.routerDelegate.currentConfiguration); (6) verify BlocListener only triggers navigation once even if the BLoC state is rebuilt. Use MockGoRouter or GoRouter test helpers. No golden tests required for this task.
Automated accessibility checks (e.g., flutter_accessibility_service) may pass while manual VoiceOver/TalkBack testing reveals focus-order issues, missing semantic roles, or live region announcements that fire too early or not at all. Discovering these late risks delaying the MVP release.
Mitigation & Contingency
Mitigation: Conduct manual VoiceOver and TalkBack testing on physical devices at the end of every sprint, not only at release. Define accessibility acceptance criteria per component and include them in the DoD. Use Semantics widgets explicitly rather than relying on implicit semantics from Flutter's default widgets for all interactive elements.
Contingency: Maintain a prioritized accessibility bug backlog separate from the main backlog. If critical VoiceOver issues are found close to release, create an explicit accessibility hotfix sprint before TestFlight distribution to Blindeforbundet testers.
Keyboard height varies significantly between iOS and Android, between device sizes (iPhone SE vs iPad), and with third-party keyboards. The KeyboardAwareLayout may not correctly adjust scroll offset in all combinations, causing input fields to remain hidden behind the keyboard on certain device/keyboard configurations.
Mitigation & Contingency
Mitigation: Test on a matrix of devices including iPhone SE (small viewport), a mid-size Android phone, and a tablet. Implement the layout using MediaQuery.viewInsets.bottom rather than a fixed padding value to correctly respond to any keyboard height. Include edge cases for floating keyboards on iPads.
Contingency: If device-specific issues are found after release, implement a bottom-padding fallback using BottomPadding inset and allow users to manually scroll. Log affected device/OS combinations for targeted fixes.
If the design token system's colour palette is updated without re-running contrast validation, form field labels, error messages, or placeholder text could fall below the WCAG 2.2 AA 4.5:1 ratio, causing a compliance regression.
Mitigation & Contingency
Mitigation: Integrate a contrast ratio validator (e.g., a CI lint step using the contrast-ratio-validator component) that checks all colour pairs used in the login form on every pull request. Document which token pairs are used for labels, errors, and backgrounds in the login form.
Contingency: If a contrast regression is detected post-merge, hot-patch the affected design token value. Do not ship a TestFlight build with known WCAG AA failures to Blindeforbundet testers.