Implement User and Activity List Filter State in BLoC
epic-admin-portal-dashboard-ui-task-014 — Add pagination and filter state management for both the user list and activity list to the AdminPortalBloc. Define filter models for user list (role filter, chapter filter, search query) and activity list (date range, type, chapter). Ensure filter state persists across tab switches within the admin portal and resets correctly when the org hierarchy scope changes.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 5 - 253 tasks
Can start after Tier 4 completes
Implementation Notes
Define UserListFilter and ActivityListFilter as immutable Dart classes with copyWith and equality (equatable or manual ==). Store both inside AdminPortalState alongside their respective PaginationState objects. Use a transformer on UpdateUserListFilter events (e.g., restartable or droppable from bloc_concurrency) to cancel in-flight queries when filters change rapidly. Implement the 300ms debounce using EventTransformer.debounce from the bloc library.
The scope-reset logic should be a single handler for OrgScopeChanged that emits a new state with filter models replaced by their const defaults — do not duplicate this logic per filter event. This pattern mirrors good practices for large admin BLoCs where many orthogonal state slices need to coexist without interfering.
Testing Requirements
Unit test with bloc_test: (1) UpdateUserListFilter with only searchQuery updates that field and resets pagination to page 1; (2) UpdateActivityListFilter with dateRange preserves other filter fields; (3) OrgScopeChanged resets both filter models to defaults; (4) tab navigation does not reset filter state (verify state identity before and after a tab-switch event); (5) ClearUserListFilter resets user filters without touching activity filters; (6) search query debounce prevents immediate service call. Use mock services returning fixed paginated results to verify correct filter parameters are forwarded.
If org node selection in AdminStateBLoC does not correctly propagate to all dependent data streams (statistics, activity log, user list, certification panel), some panels may show data from the previously selected org scope, creating a confusing and potentially dangerous mixed-scope view.
Mitigation & Contingency
Mitigation: Model org node selection as a single source of truth in AdminStateBLoC. All downstream providers derive their query parameters from this single stream via Riverpod's watch pattern. Write integration tests that verify every data stream emits a reload event when the selected node changes.
Contingency: If scope propagation bugs are detected in QA, add an explicit full-state reset on org node change (clear all cached data and refetch from scratch) as a safe but less efficient fallback until the targeted propagation is fixed.
The Admin Dashboard Screen must adapt its layout for Flutter Web (wider viewports, mouse interaction, larger grid) and mobile embedding. Flutter Web responsive layout support has historically required non-trivial workarounds, and the adaptive grid may introduce significant additional development time.
Mitigation & Contingency
Mitigation: Define breakpoints and grid behaviour in the design system before implementation. Use LayoutBuilder with explicit breakpoint constants rather than MediaQuery scattered across widgets. Prototype the web layout with a skeleton screen before implementing live data binding.
Contingency: If web layout proves intractable within sprint, deliver a mobile-first layout for all platforms initially and track a dedicated web-optimisation task for the next sprint.
A bug in the Role Assignment Panel's permission scope validation could allow an org_admin to assign roles beyond their authority (e.g., assigning super_admin to a user), representing a serious privilege escalation vulnerability.
Mitigation & Contingency
Mitigation: Enforce role assignment scope on both the client (disable unavailable roles in the panel UI) and the server (UserManagementService validates the target role is within the admin's permitted scope before persisting). Write security-focused tests that attempt out-of-scope role assignments and assert rejection.
Contingency: If an escalation vulnerability is discovered, immediately disable the role assignment panel via feature flag, revoke any incorrectly assigned roles, and deploy a server-side fix before re-enabling.