high priority low complexity frontend pending frontend specialist Tier 1

Acceptance Criteria

Dialog renders selected date range in human-readable format (e.g., '1 Jan 2025 – 31 Jan 2025') using the locale-aware DateFormat from intl package
Total approved claims count is displayed as a prominent numeric label with a descriptive semantic label for screen readers
Skipped claims section lists each skipped item with a reason enum mapped to a user-facing string: 'Already exported' or 'Outside selected range'
Target exporter name label shows 'Xledger' or 'Microsoft Dynamics 365' based on org configuration — never a raw enum value
When duplicate-export guard fires, a distinct caution banner (amber/warning color token) appears above the action buttons with the message 'An export already exists for this period'
The duplicate warning banner includes the existing export run date to help the coordinator decide whether to proceed
Dialog has two action buttons: 'Cancel' (dismisses without exporting) and 'Confirm Export' (disabled when duplicate warning is shown until coordinator explicitly checks an override checkbox)
All interactive elements have Semantics wrappers with meaningful labels, hints, and button roles
Focus is trapped within the dialog while open; focus moves to the first interactive element on open and returns to the trigger button on dismiss
Dialog is dismissed on Android back button press (same as Cancel action)
Widget renders correctly at font scale factors 1.0, 1.5, and 2.0 without overflow
Dialog passes WCAG 2.2 AA contrast ratio (minimum 4.5:1 for text) for all text and icon elements

Technical Requirements

frameworks
Flutter
BLoC
Riverpod
data models
activity
annual_summary
performance requirements
Dialog must open within 100ms of trigger — all data must be pre-fetched by the BLoC before dialog is shown
No async calls inside dialog build method — receive all data via constructor or watch a pre-loaded provider
security requirements
Do not display claim amounts or personal beneficiary data in the confirmation dialog — show only aggregate counts
Duplicate export override action must be logged as a claim_event audit record with actor_role coordinator
ui components
ExportConfirmationDialog (StatelessWidget receiving ExportSummary model)
DuplicateExportWarningBanner (reusable caution banner widget)
SkippedClaimsDetailList (expandable list of skipped items with reason chips)
OverrideCheckbox (with explicit Semantics label 'I understand this period has already been exported')

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Use showModalBottomSheet or showDialog — prefer showDialog for this confirmation use-case to enforce focus trapping via AlertDialog's built-in barrier. Pass the fully-resolved ExportSummary object as a constructor parameter rather than reading from a provider inside the dialog to keep it pure and testable. Map SkipReason enum values to localised strings in a dedicated extension method, not inline in the widget. The duplicate caution banner should use the warning color token from the design token system (not a hardcoded color).

The override checkbox state should be local ephemeral state (StatefulWidget or flutter_hooks) since it does not need to survive navigation. Avoid Navigator.pop() with a return value pattern — instead dispatch a BLoC event (ConfirmExport or CancelExport) from inside the dialog callbacks so the BLoC owns the state transition.

Testing Requirements

Unit tests: verify dialog renders all summary fields from a mock ExportSummary model; verify duplicate warning banner visibility toggled by isDuplicate flag; verify Confirm button disabled state when isDuplicate=true and override unchecked. Widget tests: pump dialog with various ExportSummary configurations (0 skipped, multiple skipped, duplicate flag on/off) and assert rendered text matches inputs. Accessibility tests: use flutter_test semantics tester to verify all Semantics nodes have labels; verify focus order with FocusTrap. Golden tests: render dialog in normal state and duplicate-warning state at 1.0 and 1.5 font scale.

Test coverage target: 90%+ for dialog widget logic.

Component
Export Confirmation Dialog
ui low
Epic Risks (2)
medium impact medium prob technical

Export operations may take several seconds, and the UI must handle all intermediate states (loading, partial success, failure, duplicate warning) without leaving the coordinator on a blank or unresponsive screen. Missing state handling causes confusion and potentially double-submissions.

Mitigation & Contingency

Mitigation: Design the BLoC state machine with explicit states for each transition before writing any widget code: ExportIdle, ExportDuplicateWarning, ExportInProgress, ExportSuccess, ExportPartialSuccess, ExportFailed. Each state maps to a distinct UI. Widget tests cover all states.

Contingency: If a loading state is missed in production, surface a generic error state with a retry action rather than leaving the UI stuck. Add a timeout on the Edge Function call (default 30 seconds) that transitions to ExportFailed with a user-readable message.

high impact medium prob technical

The custom Export Date Range Picker may not be fully navigable with VoiceOver if the underlying Flutter date widgets do not expose the correct semantic tree. This is a critical accessibility failure for Blindeforbundet users who rely on screen readers.

Mitigation & Contingency

Mitigation: Use Flutter's built-in DateRangePicker as the base and wrap with explicit Semantics nodes for start and end labels. Test with VoiceOver on a physical iOS device as part of the definition of done for this component. Reference the existing AccessibilityTestHarness pattern used elsewhere in the app.

Contingency: If the custom picker fails accessibility audit, replace it with two independent DatePicker fields (start and end) using Flutter's standard accessible date input, which has broader VoiceOver support than range variants.