high priority medium complexity testing pending frontend specialist Tier 5

Acceptance Criteria

All text on CertificationStatusScreen, RecordRenewalScreen, and CertificationsExpiringWidget passes 4.5:1 contrast ratio for normal text (< 18pt / < 14pt bold)
All large text (≥ 18pt or ≥ 14pt bold) passes 3:1 contrast ratio minimum
All interactive elements (buttons, form fields, toggles) on all three screens have meaningful Semantics labels that describe purpose, not just appearance
Focus traversal order on RecordRenewalScreen form follows logical reading order (top-to-bottom, label before field) and is verified with Flutter's FocusTraversalGroup
Status changes on CertificationStatusScreen (e.g., cert expired, cert renewed) trigger a live region announcement readable by TalkBack and VoiceOver
Form submission feedback on RecordRenewalScreen (success, error, loading) is announced via SemanticsService.announce() or equivalent live region mechanism
CertificationsExpiringWidget expiry badges include text alternatives — expiry date and urgency level are not conveyed by color alone
All touch targets on all three screens meet the 48Ă—48dp minimum as per WCAG 2.2 AA Success Criterion 2.5.8
No accessibility violations are reported by flutter_test semantics tree assertions for any of the three screens
Manual VoiceOver (iOS) walkthrough of all three screens completes without skipped elements, incorrect labels, or broken focus traps

Technical Requirements

frameworks
Flutter
flutter_test
data models
Certification
CertificationRenewal
performance requirements
Semantics tree construction must not add more than 2ms to frame render time on target devices
Live region announcements must fire within 300ms of the triggering state change
security requirements
Semantics labels must not expose internal IDs, raw database keys, or PII beyond what is visually presented
ui components
CertificationStatusScreen
RecordRenewalScreen
CertificationsExpiringWidget
Semantics widget wrappers
MergeSemantics / ExcludeSemantics where appropriate
FocusTraversalGroup for form ordering

Execution Context

Execution Tier
Tier 5

Tier 5 - 253 tasks

Can start after Tier 4 completes

Implementation Notes

Start by running Flutter's built-in accessibility checker: wrap each screen's test with `expect(tester, meetsGuideline(textContrastGuideline))` to get an automated baseline. For live regions, use `SemanticsService.announce(message, textDirection)` inside BLoC state listeners — avoid announcing on every rebuild, only on meaningful state transitions (idle→loading→success/error). Fix focus order on RecordRenewalScreen by wrapping the form in a FocusTraversalGroup with an OrderedTraversalPolicy, assigning FocusTraversalOrder widgets to each label+field pair. For the CertificationsExpiringWidget, expiry urgency (e.g., 'expires in 3 days') should be encoded in the Semantics label string directly so color-blind and screen reader users get the same information.

Use MergeSemantics around icon+label pairs to prevent double-reading. Avoid ExcludeSemantics on decorative elements that happen to carry state information — audit each exclusion manually. All contrast values should be pulled from the AccessibilityDesignTokenEnforcer (task epic-cognitive-accessibility-foundation-task-005) once available; until then, assert against hardcoded WCAG thresholds.

Testing Requirements

Unit tests: write flutter_test widget tests for each screen asserting semantics tree structure — use tester.getSemantics() to verify labels, roles, and live region flags on key nodes. Contrast tests: write a helper that reads design token color pairs and asserts minimum contrast ratios using the WCAG relative luminance formula; run it as a unit test to prevent regressions. Integration tests: perform a full screen traversal simulation using AccessibilityGuideline assertions (meetsGuideline(androidTapTargetGuideline), meetsGuideline(iOSTapTargetGuideline), meetsGuideline(labeledTapTargetGuideline)). Manual tests: conduct a full VoiceOver walkthrough on a physical iOS device covering all three screens, including form submission and expiry state changes; document findings in a checklist.

Regression: add these tests to CI so any future widget change that breaks semantics is caught before merge.

Epic Risks (3)
high impact medium prob technical

Flutter date pickers have historically poor screen reader support (VoiceOver/TalkBack), which is especially critical for this feature given that HLF peer mentors may have hearing impairment and the broader user base includes people with visual impairments. An inaccessible date picker on RecordRenewalScreen could block coordinator workflows entirely.

Mitigation & Contingency

Mitigation: Evaluate and adopt a third-party accessible date picker widget with verified WCAG 2.2 AA support, or build a custom picker using Flutter Semantics wrappers following the pattern established by the accessibility epic. Test all date pickers against VoiceOver on iOS and TalkBack on Android before UI sign-off.

Contingency: If no accessible date picker is available in time, provide a manual text field fallback for date entry (ISO format with clear labelling) alongside the picker, ensuring keyboard and screen reader users are never blocked.

medium impact high prob scope

Course enrolment initiation may redirect the user to the external HLF course portal (deep link or browser), which breaks the in-app flow and may confuse users expecting a seamless experience. The course data structure from Dynamics may also not be available in a machine-readable format in time for the initial release.

Mitigation & Contingency

Mitigation: Agree with HLF on whether enrolment is in-app or via deep link before UI design begins. If course data is not available from Dynamics at launch, design the enrolment prompt as a placeholder CTA that links to the HLF course portal homepage with a clear label indicating the user is leaving the app.

Contingency: Ship the course enrolment prompt as a configurable deep link per org. If Dynamics integration is delayed, the feature flag for the enrolment section can be disabled without affecting the rest of the certification status screen.

medium impact medium prob scope

Coordinators may attempt to record a renewal with an expiry date earlier than the previous certification's expiry (e.g., data entry error), or attempt to back-date a renewal. Without strict validation, the renewal history timeline could become chronologically inconsistent and mislead peer mentors about their coverage.

Mitigation & Contingency

Mitigation: CertificationManagementService validates that new expiry_date > current date and new issue_date >= previous renewal's issue_date before persisting. Surface validation errors as plain-language messages on RecordRenewalScreen using the error_message_registry pattern.

Contingency: If invalid renewal entries are discovered in production (from pre-validation data), provide a coordinator-only correction flow (edit renewal entry) behind an admin feature flag to fix historical records without requiring a full reset.