critical priority medium complexity frontend pending frontend specialist Tier 7

Acceptance Criteria

Every checkbox item row has a minimum touch/tap target of 44×44 dp, enforced via SizedBox constraints or GestureDetector padding around the entire row
Each checkbox item exposes semanticsLabel combining mentor name and checked state, e.g., 'Anna Berg, checked' / 'Anna Berg, unchecked' — verified via Semantics debugger
The select-all toggle exposes a Semantics role of 'checkbox' with the current tri-state value (true/false/mixed) so VoiceOver announces 'Select all, checked/unchecked/mixed'
The selected-count badge is wrapped in Semantics(liveRegion: true) so VoiceOver/TalkBack announces the updated count when it changes, without shifting focus
The search field has a Semantics label 'Search peer mentors' and announces result count after filtering, e.g., '3 of 12 mentors shown'
All text and icon colors in the component meet WCAG 2.2 AA contrast ratio of at least 4.5:1 against their backgrounds (verified with a contrast checker against design token values)
The count badge text has at least 4.5:1 contrast against its background color (design token validation)
Focus traversal order via keyboard or switch access follows a logical top-to-bottom sequence: search bar → select-all toggle → list items → continue button
No focus traps: the user can navigate into and out of the list using sequential focus (Tab/switch-access next)
Screen reader users can complete the full flow (search, select, continue) without requiring touch gestures — fully operable via linear navigation
Flutter accessibility guidelines are met: no decorative-only Semantics nodes cluttering the tree, meaningful labels on all interactive elements

Technical Requirements

frameworks
Flutter
performance requirements
Semantics tree updates must not introduce frame drops — use const Semantics widgets where label is static
security requirements
Semantics labels must not expose sensitive coordinator or mentor PII beyond display name
ui components
MentorListItem (wrap row in Semantics with label and checked properties)
SelectAllToggleWidget (Semantics with checkbox role and tri-state value)
SelectedCountBadge (Semantics liveRegion)
MentorSearchBar (Semantics label + result-count announcement)

Execution Context

Execution Tier
Tier 7

Tier 7 - 84 tasks

Can start after Tier 6 completes

Implementation Notes

Touch target: wrap the entire MentorListItem row in a Material widget with InkWell (provides 48dp ripple by default) or explicitly set constraints via ConstrainedBox(constraints: BoxConstraints(minHeight: 44, minWidth: 44)). For checkbox semantics, use Semantics(checked: isSelected, label: mentorName, onTap: ..., child: ...) and set excludeSemantics: true on the inner Checkbox widget to prevent duplicate announcements. For the tri-state select-all, Flutter's Checkbox widget has a tristate: true property — use it with value: null for indeterminate, true for all selected, false for none. The Semantics wrapper should pass value: null correctly.

For contrast: reference design token colors (AppColors.textPrimary on AppColors.surface, etc.) and verify against WCAG formula at build time or in a dedicated test. For focus order: Flutter respects widget tree order for traversal by default; ensure the widget hierarchy is search bar → select-all → ListView → continue button. Use FocusTraversalGroup if manual ordering is needed. Avoid MergeSemantics on rows that contain multiple interactive elements (checkbox + row tap) — use a single Semantics node for the whole row instead.

Testing Requirements

Accessibility widget tests using flutter_test SemanticsController: (1) Assert every MentorListItem has a Semantics node with isChecked/isNotChecked set correctly. (2) Assert SelectAllToggle has a Semantics node with hasCheckedState and correct value. (3) Assert SelectedCountBadge Semantics node has liveRegion: true. (4) Assert search field Semantics node has label 'Search peer mentors'.

(5) Verify focus order by traversing Semantics tree nodes and asserting correct sequence. Manual testing on-device: VoiceOver (iOS) and TalkBack (Android) end-to-end walkthrough — screen reader must announce every state change without requiring sighted assistance. Contrast verification: automated test asserting design token color values meet 4.5:1 ratio (use a helper that computes relative luminance from hex values).

Component
Peer Mentor Multi-Select List
ui medium
Epic Risks (2)
medium impact medium prob technical

NHF coordinators may manage dozens of peer mentors across multiple chapters. If the multi-select list renders all contacts in a single unsorted ListView, performance degrades with 50+ items, and coordinators cannot efficiently locate a specific mentor, increasing the probability of selection errors and wrong-person proxy registrations.

Mitigation & Contingency

Mitigation: Use a SliverList with itemExtent for fixed-height rows to enable O(1) scroll position calculation. Implement the search filter using a debounce utility operating on an in-memory list (no extra API calls). Sort the contact list alphabetically by default. Add chapter-filter chips above the list for NHF's multi-chapter coordinators.

Contingency: If performance issues arise in testing with real data sets, introduce pagination with a 'load more' trigger at the bottom of the list and cache rendered rows using Flutter's AutomaticKeepAliveClientMixin.

high impact medium prob security

NHF has a complex 12-national-association / 9-region / 1,400-chapter hierarchy. It is ambiguous whether a coordinator can proxy-register for peer mentors outside their immediately assigned chapter. If the contact list is not correctly scoped by RLS, coordinators might see — and register on behalf of — peer mentors they do not manage, creating fraudulent activity records that skew Bufdir statistics.

Mitigation & Contingency

Mitigation: The Proxy Contact List Provider must query only peer mentors linked to the coordinator's own chapter scope via RLS. Add an explicit Supabase query test asserting that a coordinator from chapter A cannot retrieve peer mentors from chapter B. Display each mentor's chapter affiliation in the list row so coordinators can visually verify scope.

Contingency: If RLS scope is found to be too permissive in testing, apply a server-side coordinator_id filter as a secondary guard on the query. Block the feature release until the scope test passes consistently.