high priority low complexity testing pending testing specialist Tier 3

Acceptance Criteria

All text elements in PeriodPresetList and CustomDateRangePicker achieve a minimum contrast ratio of 4.5:1 (WCAG 2.2 AA) in both light and dark themes
Interactive elements (buttons, list items, date inputs) achieve a minimum contrast ratio of 3:1 for UI component boundaries against adjacent colours
Every interactive element has a touch target of at least 44×44dp (WCAG 2.5.5)
All controls expose a non-empty Semantics label attribute readable by TalkBack (Android) and VoiceOver (iOS)
Keyboard / switch-access focus order moves logically top-to-bottom through preset items then into date range fields
Validation error messages are wrapped in a Semantics widget with liveRegion: true so they are announced without requiring focus shift
No audit failure items remain unresolved — all findings are either fixed in code or documented as accepted risk with justification
A short audit findings document (markdown or inline code comment block) is committed alongside the widget source listing each WCAG criterion checked, result (pass/fail/fixed), and fix applied

Technical Requirements

frameworks
Flutter
flutter_test (SemanticsController)
Riverpod
data models
accessibility_preferences
performance requirements
Audit tooling must not require a physical device — automated assertions must run in CI via flutter_test
security requirements
Audit must cover the visual rendering in both default and high-contrast modes if accessibility_preferences.contrast_mode is implemented
ui components
PeriodPresetList
CustomDateRangePicker

Execution Context

Execution Tier
Tier 3

Tier 3 - 413 tasks

Can start after Tier 2 completes

Implementation Notes

Start with automated SemanticsController assertions in a widget test to catch missing labels early without a device. Then follow up with manual screen reader testing on emulators to catch announcement ordering issues that automated tests miss. For live region error announcements, wrap the error Text in Semantics(liveRegion: true, child: ...) — Flutter will emit the appropriate platform accessibility event. For contrast: use design tokens from the shared token file rather than hardcoded hex values; if a token fails contrast, update the token, not an inline colour.

Ensure CustomDateRangePicker uses ExcludeSemantics on purely decorative icons (calendar icon, separator dash) to avoid screen reader noise. For the accessibility_preferences.font_scale_factor, verify widgets do not overflow at scale factors up to 2.0.

Testing Requirements

Use flutter_test's SemanticsController to assert semantic labels and live regions programmatically. Run manual TalkBack (Android emulator) and VoiceOver (iOS simulator) smoke tests for focus order and announcement quality. Use a contrast analysis tool (e.g. browser DevTools colour picker or Flutter's Accessibility Scanner) to verify contrast ratios against the design token colour values in styles.

Document results per WCAG success criterion: 1.4.3 (contrast minimum), 1.4.11 (non-text contrast), 2.4.3 (focus order), 2.5.5 (target size), 4.1.3 (status messages).

Component
Custom Date Range Picker
ui low
Epic Risks (3)
high impact medium prob security

Supabase RLS policies for period preset configuration may be missing or incorrectly scoped, causing one organisation's presets to leak to another or write operations to fail silently.

Mitigation & Contingency

Mitigation: Define and review RLS policies for the bufdir_period_presets table in the migration file before any repository code is written. Include an integration test that verifies cross-organisation isolation using two distinct org credentials.

Contingency: If RLS is misconfigured in production, immediately disable the period preset fetch endpoint and fall back to hardcoded global presets until the policy is corrected and redeployed.

medium impact medium prob technical

The activities table may lack a composite index on (organisation_id, activity_date), causing the range count query in BufdirAggregationRepository to perform a full table scan and exceed acceptable response time for large organisations.

Mitigation & Contingency

Mitigation: Add a migration that creates a composite index on (organisation_id, activity_date) as part of this epic. Benchmark the count query against a representative dataset (10 000+ rows) before marking the epic complete.

Contingency: If query latency is unacceptable after indexing, move the count query to a Supabase RPC function that leverages a materialised view or partial index, accepting a slight staleness window.

medium impact medium prob technical

Flutter's native date picker widgets have known accessibility gaps (missing semantic labels, non-standard focus traversal) that may prevent WCAG 2.2 AA compliance out of the box, requiring a custom implementation.

Mitigation & Contingency

Mitigation: Evaluate third-party accessible date picker packages (e.g., table_calendar with custom semantics) against WCAG 2.2 AA criteria before beginning implementation. Document the chosen approach in the epic kick-off.

Contingency: If no package meets accessibility requirements, implement a simple text-field-based date entry with explicit semantic labels and format hints as an accessible fallback, deferring a fully visual calendar to a later iteration.