high priority medium complexity frontend pending frontend specialist Tier 5

Acceptance Criteria

Widget displays a list of all unit assignments for the target user, each showing unit name, unit type (chapter/region/national/local), and a 'Primary' badge if that unit is the primary assignment
Only one unit can be marked as primary at a time — selecting a new primary radio deselects the previous one
Tapping the 'Add Assignment' button opens a unit picker (modal or bottom sheet) filtered to units the admin has authority over
After selecting a unit in the picker, the assignment is created via UnitAssignmentService and the list updates without full screen reload
Tapping remove on an assignment shows a confirmation dialog before calling UnitAssignmentService.removeAssignment()
If removal targets the primary unit and other units remain, user is prompted to select a new primary before confirming removal
If the user has no assignments, an empty state message is shown with a prominent 'Add Assignment' call-to-action
All mutations (add, remove, set primary) show a loading indicator on the affected row and disable other actions during the operation
Widget is embeddable in both UserDetailScreen and HierarchyAdminPortalScreen without layout overflow
WCAG 2.2 AA: all touch targets ≥ 48dp, contrast ratios met, and radio/badge states announced by screen reader
Error states (network failure, permission denied) display inline error messages with retry option

Technical Requirements

frameworks
Flutter
BLoC (flutter_bloc)
apis
UnitAssignmentService.getAssignments(userId)
UnitAssignmentService.addAssignment(userId, unitId)
UnitAssignmentService.removeAssignment(userId, unitId)
UnitAssignmentService.setPrimaryUnit(userId, unitId)
Supabase REST (unit assignments table)
data models
UnitAssignment
Unit
UserProfile
performance requirements
Assignment list renders without jank for up to 10 assignments per user
Mutation operations provide optimistic UI update within 100ms, with rollback on error
Widget mounts and renders in under 100ms from parent context
security requirements
Only admin and coordinator roles can interact with mutation controls — render panel as read-only for non-admin viewers
Supabase RLS must enforce that only authorized admins can mutate assignments for a given user
Unit picker must only show units within the admin's own authority scope
ui components
UnitAssignmentListTile (unit name, type chip, primary badge, remove button)
PrimaryUnitRadioControl
UnitPickerBottomSheet or UnitPickerModal
RemoveAssignmentConfirmationDialog
EmptyAssignmentsState widget
InlineErrorWidget with retry
RowLoadingOverlay for per-row mutation state

Execution Context

Execution Tier
Tier 5

Tier 5 - 253 tasks

Can start after Tier 4 completes

Implementation Notes

Design this as a self-contained UnitAssignmentPanel widget that accepts a userId parameter and manages its own BLoC (UnitAssignmentCubit). This allows embedding in any screen without the parent managing assignment state. Use optimistic updates: immediately update the local list on mutation, then sync with the server; revert on error and show a snackbar. For the radio button pattern, do not use Flutter's RadioListTile directly if it conflicts with design tokens — build a custom tile with a leading CircleAvatar or Icon toggled by the cubit state.

The unit picker should be a separate widget (UnitPickerSheet) that returns a selected Unit? via Navigator.pop, so the panel can handle the result cleanly. Implement the 'remove primary unit with remaining assignments' edge case explicitly: show a secondary dialog asking 'Select new primary before removing'.

Testing Requirements

Write widget tests covering: (1) list renders all assignments with correct unit name, type, and primary badge, (2) only one item can be primary at a time, (3) remove triggers confirmation dialog, (4) confirmed remove calls UnitAssignmentService.removeAssignment and removes item from list, (5) add assignment button opens unit picker, (6) empty state renders when list is empty, (7) loading state shown during mutation, (8) error state shown on service failure with retry button. Mock UnitAssignmentService in all tests. Integration test: add and remove assignment against a Supabase test instance. Aim for 85%+ widget coverage.

Component
Unit Assignment Panel
ui medium
Epic Risks (3)
high impact medium prob security

If the AccessScopeService and the Supabase RLS policies use different logic to determine accessible units, a coordinator could see data in the client that RLS blocks server-side, causing confusing empty states, or worse, RLS could block data the scope service declares accessible.

Mitigation & Contingency

Mitigation: Define the canonical scope computation in a single Supabase Postgres function shared by both the RLS policies and the RPC endpoint called by AccessScopeService. The client-side service calls this RPC rather than reimplementing the logic, ensuring a single source of truth.

Contingency: Add integration tests that execute the same access decision through both the RLS policy path and the AccessScopeService path and assert identical results. Use these as regression guards in the CI pipeline.

medium impact medium prob integration

When a user switches active chapter via the ChapterSwitcher, widgets that are already built may not receive the context-change event if they subscribe incorrectly to the ActiveChapterState BLoC, leading to stale data being displayed under the new chapter context.

Mitigation & Contingency

Mitigation: Use Riverpod's ref.watch on the active chapter provider at the root of each scoped data subtree rather than at individual leaf widgets. Trigger a global data refresh by invalidating all scoped providers when the chapter changes.

Contingency: Add an app-level chapter-change listener that forces a full navigation stack reset to the home screen on chapter switch, guaranteeing all widgets rebuild from scratch with the new context. Accept the UX cost of navigation reset for correctness.

medium impact medium prob scope

Non-technical organization administrators may find the hierarchy management interface too complex for the structural changes they need to make frequently (e.g., chapter renaming, coordinator reassignment), leading to low adoption and continued reliance on manual processes.

Mitigation & Contingency

Mitigation: Conduct usability testing with at least one NHF administrator before finalizing the admin portal screen layout. Prioritize the most common operations (rename, reparent, add child) as primary actions in the UI. Include inline help text and confirmation dialogs with plain-language descriptions of consequences.

Contingency: Provide a simplified 'quick edit' mode that exposes only the three most common operations (rename, deactivate, add child) and hides advanced structural operations behind an 'Advanced' toggle.