Navigation to individual user profile
epic-admin-portal-user-management-task-011 — Implement navigation from the user list row to the individual user profile detail screen. Pass the user ID via route arguments, ensure back navigation returns to the list at the correct scroll position with filters preserved, and confirm deep-link compatibility for direct access to user profiles.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 5 - 253 tasks
Can start after Tier 4 completes
Implementation Notes
Preserve scroll position by storing the ScrollController's offset in the UserManagementBloc state (or a dedicated ListScrollState) before pushing the route, and restoring it in a post-frame callback on return. With GoRouter, use the `extra` parameter to pass the pre-fetched user summary object alongside the userId, so the profile screen can render immediately from the already-loaded data while optionally refreshing in the background. For deep links, the profile screen must be able to fetch user data independently via UserManagementService.getUserById() when navigated to without `extra` data. Register the route as `/admin/users/:userId` in the router configuration.
Use `onPopInvoked` or `PopScope` (Flutter 3.16+) for back navigation handling if custom logic is needed beyond simple pop. Avoid storing scroll position in a global singleton — keep it in the BLoC to allow proper disposal.
Testing Requirements
Widget tests: (1) tapping a user row triggers navigation with the correct userId argument; (2) back navigation pops the profile screen. Integration tests: (1) navigate from list → profile → back; verify scroll position and filter state are restored using a ScrollController and BLoC state inspection. Deep-link test: construct a GoRouter link `/admin/users/test-uuid`, navigate programmatically, verify profile screen renders with correct userId. Test on both iOS simulator and Android emulator to catch platform-specific back gesture differences.
Displaying NHF users with membership in up to 5 local chapters in a flat list view without duplicating entries requires a non-trivial aggregation query. Incorrect query design could result in duplicated user rows or missing chapter affiliations, confusing admins and causing incorrect role assignments.
Mitigation & Contingency
Mitigation: Design the user list query to GROUP BY user_id and aggregate chapter affiliations as an array field. Use AdminRepository's typed models to surface this aggregated structure to the UI. Validate with a test dataset containing users in 5 chapters.
Contingency: If aggregation query complexity proves too high for real-time filtering, implement a separate multi-chapter affiliation fetch triggered only when a specific user row is expanded, reducing query complexity for the base list.
Composable multi-dimensional filters (role + chapter + status + certification state) applied server-side against an org with 2,000+ users may produce slow queries, particularly when filtering by certification state requires joining an additional table.
Mitigation & Contingency
Mitigation: Ensure the relevant filter columns (role, status, chapter_id, certification_expiry) are indexed in Supabase. Use cursor-based pagination rather than OFFSET to maintain consistent performance at high page numbers. Profile filter query combinations against a large dataset during development.
Contingency: If multi-filter performance degrades in production, introduce a denormalised search index table updated on user status changes, allowing the list query to filter from a single table.
Deactivating a user account that has ongoing activity assignments, open expense claims, or active chapter affiliations may leave orphaned records or break downstream workflows if the deactivation does not trigger correct cascade handling.
Mitigation & Contingency
Mitigation: Define and document the expected state of each dependent record type on user deactivation before implementing the toggle. Implement deactivation as a UserManagementService operation that checks for and warns about open dependencies before persisting. Write integration tests covering each dependency type.
Contingency: If orphaned record issues are discovered post-launch, provide an admin-accessible reconciliation view that surfaces users with inconsistent dependency states and allows manual resolution without requiring a code deploy.