critical priority high complexity frontend pending frontend specialist Tier 1

Acceptance Criteria

Selecting an org unit via SelectOrgScope event updates AdminPortalState.selectedOrgScope and immediately resets pagination (page=0) and clears stale data
All downstream Riverpod providers (dashboardStatsProvider, activityLogProvider, certificationPanelProvider, exportScopeProvider) react to scope changes within one frame
Downstream providers use the selectedOrgScope from AdminPortalBloc as a dependency — changing scope invalidates and re-fetches their data
Clearing org scope (ClearOrgScope event) resets all downstream providers to their global (unscoped) state
Scope selection supports all three hierarchy levels: org (top), region (mid), chapter (leaf) — each level filters data correctly
An admin cannot select a scope outside their permitted hierarchy — the BLoC validates against the user's accessible nodes and emits an error state if violated
UI updates reflect the new scope within 300ms of selection (perceived responsiveness, loading states shown immediately)
Scope changes are debounced by 100ms to prevent rapid-selection flooding downstream providers
The currently selected scope persists in state for the session — navigating between dashboard tabs does not reset the scope
BLoC unit tests cover scope propagation with mock downstream providers verifying invalidation calls

Technical Requirements

frameworks
flutter_bloc
riverpod
apis
AdminStatsRepository
ActivityLogRepository
CertificationRepository
OrgHierarchyRepository
data models
OrgNode
AdminPortalState
SelectOrgScope
ClearOrgScope
DashboardStats
ActivityFilterParams
performance requirements
Scope change propagation to all providers completes within one frame (16ms)
Debounce 100ms on rapid scope changes to avoid redundant API calls
Each downstream provider must independently cache and invalidate — no waterfall dependency chains
security requirements
Scope selection must enforce server-side org access control — the Supabase RLS policies must also restrict data to the selected scope, not just the client-side filter
Org node IDs must be validated against the authenticated user's allowed orgs list before adding to state
ui components
OrgHierarchyNavigator (triggers SelectOrgScope events)
ScopeBadge (displays current scope in dashboard header)

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Implement scope propagation by exposing the selected org scope as a Riverpod StateProvider derived from the AdminPortalBloc state stream. Downstream providers watch this derived provider and automatically re-fetch when it changes. Use riverpod's ref.watch(orgScopeProvider) pattern in each downstream provider's build method — this ensures automatic invalidation without manual coordination. For debouncing, use a Timer in the BLoC's event handler that cancels any pending scope change before scheduling the new one.

The org hierarchy data (available nodes for the current admin) should be loaded once on BLoC init and cached in state — do not re-fetch the hierarchy on every scope change. Validate the selected node against the cached hierarchy list in the SelectOrgScope handler before emitting the new state. For NHF's complex hierarchy (12 landsforeninger, 9 regioner, 1400 lokallag), ensure the scope propagation model is lazy — only load child data when a scope is actually selected, not upfront.

Testing Requirements

BLoC unit tests using bloc_test. Cover: (1) SelectOrgScope with valid org-level node, (2) SelectOrgScope with valid region-level node, (3) SelectOrgScope with valid chapter-level node, (4) SelectOrgScope with unauthorized node emits error, (5) ClearOrgScope resets to null scope, (6) scope change resets pagination state, (7) rapid scope changes debounced (emit only final state). Widget integration tests: mount AdminDashboardScreen in a ProviderScope with mock providers, fire a scope change, assert all provider data refreshes. Use Riverpod's ref.invalidate() pattern in downstream providers and verify it's called on scope change.

Component
Admin Portal BLoC
data high
Epic Risks (3)
high impact medium prob technical

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.

medium impact medium prob technical

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.

high impact low prob security

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.