high priority medium complexity frontend pending frontend specialist Tier 9

Acceptance Criteria

Every interactive element (buttons, tap targets, refresh indicator) has a non-empty semanticsLabel that describes its action in Norwegian (or the active locale)
CircularProgressIndicator in loading state is wrapped in Semantics(label: 'Laster inn detaljer for likeperson', liveRegion: true) so screen readers announce it automatically
Per-section fallback text widgets are wrapped in Semantics(label: '<section> data utilgjengelig') so TalkBack/VoiceOver reads them as announcements when they appear
CertificationAlertBanner tap target has a minimum hit area of 44×44 logical pixels enforced via SizedBox or Padding — verified with a layout test
CertificationAlertBanner Semantics node has button role, label 'Sertifisering utløpt – trykk for å melde deg på kurs', and hint 'Navigerer til kurspåmelding'
Profile image in PeerMentorProfileHeader has Semantics(label: '<mentorName> profilbilde') or Semantics(excludeSemantics: true) if purely decorative
AssignedContactsList items each have a unique semantic label combining contact name and role
Focus order follows the visual reading order (top to bottom, left to right) — verified by stepping through with TalkBack on an Android emulator
No Semantics(excludeSemantics: true) is applied to content-bearing widgets — only decorative elements are excluded
All color-conveyed information (certification status colors) is also communicated via text label in the Semantics tree
Text contrast ratio meets WCAG 2.2 AA minimum 4.5:1 for normal text and 3:1 for large text — verified using Flutter's color contrast analyzer or manual calculation against design tokens

Technical Requirements

frameworks
Flutter
flutter_test (for semantics testing)
data models
PeerMentorDetailModel
CertificationModel
performance requirements
Semantics widgets must not introduce additional layout passes — use Semantics as a thin wrapper, not a layout widget
liveRegion announcements must fire within one frame of the state change to Loading
security requirements
Semantics labels must not expose sensitive PII (e.g., national ID, health data) — use role/title information only in labels
Screen reader announcements for error states must not reveal internal error codes or API details
ui components
Semantics (Flutter core widget)
SizedBox / Padding (for minimum touch target enforcement)
ExcludeSemantics (for decorative elements only)
MergeSemantics (for grouped semantic nodes)

Execution Context

Execution Tier
Tier 9

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.

Component
Peer Mentor Detail Screen
ui medium
Epic Risks (3)
medium impact medium prob technical

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.

medium impact medium prob integration

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.

low impact high prob dependency

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.