Apply WCAG 2.2 AA semantics throughout full screen
epic-peer-mentor-detail-screen-bloc-and-assembly-task-011 — Audit and annotate the entire PeerMentorDetailScreenWidget and all its assembled sub-components with Flutter Semantics widgets. Ensure all interactive elements have semantic labels, role announcements work correctly with VoiceOver/TalkBack, loading state announces progress, per-section error states announce fallback messages, and the certification expiry tap target meets 44x44pt minimum touch target size per WCAG 2.2 AA.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 9 - 22 tasks
Can start after Tier 8 completes
Implementation Notes
Use SemanticsService.announce() for dynamic announcements like state changes rather than embedding liveRegion in static Semantics nodes — this fires an immediate announcement regardless of focus. For the 44×44pt minimum touch target on CertificationAlertBanner, wrap the GestureDetector (or InkWell) in a ConstrainedBox(constraints: BoxConstraints(minWidth: 44, minHeight: 44)) — do not use padding alone as it does not expand the hit test area in all cases. For color-only information in CertificationStatusBadge, add a visually hidden Semantics label: `Semantics(label: 'Status: Aktiv', child: ColoredBox(...))`. Prefer Semantics with explicitChildNodes: false (the default) to allow Flutter to merge child semantics automatically — only override when the merged result is incorrect.
Keep semantic labels in the localization ARB files rather than hardcoding strings so they can be translated.
Testing Requirements
Use flutter_test's SemanticsHandle and tester.getSemantics() to assert semantic labels and roles programmatically. Write tests for: (1) loading state announces liveRegion label, (2) CertificationAlertBanner semantic node has button role and correct label, (3) each AssignedContactsList item has a unique, non-empty semantic label, (4) profile image is either labelled or excluded from semantics. Use find.bySemanticsLabel to locate widgets by their accessibility labels. Test minimum tap target size for CertificationAlertBanner using tester.getSize(find.byType(CertificationAlertBanner)) and assert both dimensions >= 44.0.
Perform manual VoiceOver (iOS) and TalkBack (Android) smoke tests on a physical device before marking complete.
The parallel Future.wait aggregation pattern may produce race conditions or incorrect merged state when some repositories resolve significantly faster than others, particularly if the BLoC receives a RefreshDetail event while a prior fetch is still in flight.
Mitigation & Contingency
Mitigation: Implement cancellation token pattern in the aggregation service to abort in-flight fetches on new events. Add BLoC test scenarios for rapid successive refresh events to validate state consistency.
Contingency: If race conditions persist, switch to a sequential-with-timeout fetch strategy for the first release and profile the performance impact before deciding whether parallel fetch optimization is worth the complexity.
Integrating PeerMentorDetailScreenWidget into the existing StatefulShellRoute navigation structure may conflict with the Contacts tab's existing route hierarchy, requiring changes to navigation-route-config that could affect other teams' features.
Mitigation & Contingency
Mitigation: Coordinate with the Contact List and Contact Detail feature teams before adding the new route. Review the existing StatefulShellRoute configuration and confirm the peer mentor detail route can be nested under the Contacts branch without path conflicts.
Contingency: If route conflicts arise, temporarily implement the peer mentor detail as a modal overlay (push route) rather than a shell route child, preserving functionality while the navigation architecture conflict is resolved.
The course enrollment screen that the certification alert banner links to may not yet exist or may be implemented in a separate feature epic, leaving a broken navigation tap for HLF users in the initial release.
Mitigation & Contingency
Mitigation: Check the certification management feature implementation status before finalizing Epic 4 scope. If the enrollment screen is not available, design the tap action to open the HLF course enrollment URL in an external browser as an interim solution.
Contingency: Implement the CTA as a configurable action: if the enrollment route exists in the router, push it; otherwise, launch the configured org-specific enrollment URL via url_launcher, ensuring HLF users can always take action on expired certifications.