high priority low complexity frontend pending frontend specialist Tier 0

Acceptance Criteria

Widget accepts a DeclarationStatus enum value and renders the correct label and color for all four states: pending, sent, acknowledged, expired
Each state uses a distinct design-token color: pending uses a neutral/warning token, sent uses a primary/info token, acknowledged uses a success token, expired uses an error/muted token — no hardcoded hex values
Badge includes a Semantics widget wrapping the visible label with an explicit semanticsLabel that reads the full state name (e.g., 'Declaration status: acknowledged')
Text meets WCAG 2.2 AA contrast ratio (minimum 4.5:1) against the badge background color for all four states
Badge renders correctly at default and at 2× text scale factor (accessibility large text)
Widget is stateless and requires no external state management
Widget is exported from the shared widgets barrel file for use across the app
A widget test verifies all four states render without overflow or exceptions
No hardcoded strings — display labels use the organization labels system or a localization key

Technical Requirements

frameworks
Flutter
Dart
data models
DeclarationStatus (enum: pending, sent, acknowledged, expired)
performance requirements
Widget must be const-constructible where possible to avoid unnecessary rebuilds
No async operations — badge renders synchronously from the passed status value
security requirements
Status label text must be sanitized — do not render any user-provided string directly as the status label; only enum-mapped strings are displayed
ui components
Container with rounded border radius (design token: radii.sm or equivalent)
Padding using design token spacing values
Text widget using design token typography style
Semantics wrapper for screen reader support
Optional leading status dot (small circle) for non-text accessibility reinforcement

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Define a DeclarationStatusBadge as a StatelessWidget with a single required status parameter of type DeclarationStatus. Use a switch expression (Dart 3) to map each status to a _BadgeConfig record containing label, backgroundColor, and textColor — all sourced from the app's ThemeData extension or design token constants. Wrap the Container+Text in a Semantics widget with excludeSemantics: true on the Text child so the screen reader reads only the explicit semanticsLabel. Place the file at lib/features/driver/widgets/declaration_status_badge.dart.

Export it from lib/features/driver/widgets/widgets.dart. Follow the pattern used by existing app badge/chip widgets (e.g., role badges) for visual consistency.

Testing Requirements

Write widget tests in test/widgets/declaration_status_badge_test.dart using flutter_test. Test each of the four DeclarationStatus values: verify the correct label text is rendered and that the Semantics widget has the correct semanticsLabel. Use tester.pumpWidget with a MaterialApp wrapper providing the design token theme. Add a golden test (or visual comparison) for each state to catch regressions.

Test at textScaleFactor: 2.0 to verify no overflow. All tests must pass with flutter test --coverage.

Component
Declaration Status Badge
ui low
Epic Risks (3)
high impact medium prob technical

The declaration acknowledgement screen has the most complex accessibility requirements of any screen in this feature: scrollable long-form legal text, a conditional checkbox that is only enabled after reading, and a timestamp capture. Incorrect focus management or missing semantics annotations could fail VoiceOver navigation or cause the screen reader to announce the checkbox as available before the driver has scrolled, undermining the legal validity of the acknowledgement.

Mitigation & Contingency

Mitigation: Build the acknowledgement screen against the WCAG 2.2 AA checklist from the start, not as a post-hoc audit. Use semantics-wrapper-widget and live-region-announcer from the platform's accessibility toolkit. Include a VoiceOver test session in the acceptance criteria with a tester using the screen reader.

Contingency: If WCAG compliance cannot be fully achieved within the sprint, ship the screen with a documented list of accessibility gaps and a follow-up sprint commitment. Do not block the declaration workflow launch if the core interaction works but a non-critical semantics annotation is missing.

medium impact medium prob integration

Drivers receive a push notification with a deep link to the declaration acknowledgement screen for a specific assignment. If the deep link handler does not correctly route to the right screen and assignment context — particularly when the app is launched cold from the notification — the driver may see a blank screen or the wrong declaration.

Mitigation & Contingency

Mitigation: Implement and test all three notification scenarios: app foregrounded, app backgrounded, and cold start. Use the platform's existing deep-link-handler infrastructure. Add integration tests that simulate notification tap events and assert correct screen and data loading.

Contingency: If cold-start deep link routing proves unreliable, implement a notification-centre fallback where the driver can find the pending declaration from the notification centre screen, ensuring the workflow can always complete even if the direct deep link fails.

medium impact low prob technical

If the driver-feature-flag-guard has any rendering edge case — such as a brief flash of driver UI before the flag value is loaded, or a guard that fails open on a flag service error — driver-specific UI elements could be momentarily visible to coordinators in organizations that have not opted in, causing confusion and potentially a support escalation.

Mitigation & Contingency

Mitigation: Default the guard to rendering nothing (not a loading indicator) until the flag value is definitively resolved. Treat flag service errors as flag-disabled to fail closed. Write widget tests covering the loading, disabled, and enabled states including the error case.

Contingency: If fail-closed cannot be guaranteed within the sprint, add a server-side RLS check on the driver assignment endpoints so that even if the UI guard leaks, the data layer refuses to return driver data for organizations without the flag enabled.