high priority high complexity frontend pending frontend specialist Tier 4

Acceptance Criteria

Tree renders the root level of the hierarchy on initial load with expand icons for nodes that have children
Tapping the expand icon fetches and renders child nodes of that node via HierarchyService (lazy loading — children not fetched until expanded)
Each node displays: node name, node type label (chapter/region/national/local), and member count badge
Only one node is selected at a time; selected node is visually highlighted with the design token accent color
Tapping a node invokes the onNodeSelected(HierarchyNode) callback with the selected node
Tree correctly renders visual indentation (16–24dp per depth level) for all nested levels
Collapse icon is shown for expanded nodes; tapping it collapses the subtree and frees rendered children from the widget tree
Search highlight: when a search string is active, all nodes matching the query are visually highlighted (background or text color change); non-matching nodes are dimmed but still visible
Tree handles 1,400+ visible nodes without frame drops — uses ListView.builder or SliverList for virtualized rendering
Loading indicator is shown at the expand position while child nodes are being fetched
Error state at node level shown if child fetch fails, with retry option
Widget is accessible: expand/collapse controls have semantic labels, selected state is announced by screen reader

Technical Requirements

frameworks
Flutter
BLoC (flutter_bloc)
apis
HierarchyService.getRootNodes()
HierarchyService.getChildNodes(parentId)
HierarchyService.searchNodes(query)
data models
HierarchyNode
HierarchyTreeState
performance requirements
Initial root load completes and renders in under 500ms on a mid-range device
Expanding a node with up to 200 children renders in under 200ms
Scrolling through 1,400+ rendered nodes maintains 60fps
Collapsed subtrees must be removed from the widget tree to free memory
security requirements
Only display nodes within the authenticated user's authority scope
HierarchyService must enforce backend authorization — never rely on client-side filtering alone
ui components
HierarchyTreeView (root widget, manages scroll)
HierarchyNodeTile (single node row: indent, expand icon, name, type, member count)
NodeLoadingTile (placeholder while children load)
NodeErrorTile (inline error with retry)
SearchHighlightText (text widget with match highlighting)

Execution Context

Execution Tier
Tier 4

Tier 4 - 323 tasks

Can start after Tier 3 completes

Implementation Notes

The key architectural decision is how to model the tree state. Use a flat list approach in the BLoC: maintain a List where each item has depth, isExpanded, isLoading, isError, and isSelected fields. The ListView.builder renders this flat list directly — indentation is applied via Padding(padding: EdgeInsets.only(left: depth * 20.0)). When a node expands, insert its children into the flat list immediately after it; when collapsed, remove them.

This avoids recursive widget trees and enables virtualization. For lazy loading, dispatch ExpandNodeEvent to the cubit which calls HierarchyService.getChildNodes(parentId), inserts a loading placeholder, then replaces it with real children. For search, maintain a separate searchQuery in the cubit state and apply highlighting in the HierarchyNodeTile using a RichText widget that splits text on matches. Do not re-fetch the entire tree on search — filter and highlight in-memory.

For NHF's 1,400 nodes, the flat list approach will comfortably handle this scale with Flutter's built-in virtualization.

Testing Requirements

Write widget tests for: (1) root nodes render on load, (2) expand fetches and shows children, (3) collapse removes children from tree, (4) selected node highlights correctly and triggers callback, (5) search highlighting marks matching nodes, (6) loading tile shown during child fetch, (7) error tile shown on fetch failure with retry. Performance test: render a flat list of 1,400 items with ListView.builder and confirm no jank in flutter_test integration mode. Unit test HierarchyTreeCubit for expand, collapse, select, and search state transitions. Aim for 90%+ cubit coverage and 80%+ widget coverage.

Component
Hierarchy Admin Portal Screen
ui high
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.