Connect re-export action buttons to coordinator
epic-bufdir-report-history-ui-task-006 — Wire the re-export action buttons on ReportHistoryListItem to the ReportReexportCoordinator via the state layer. Tapping re-export must trigger the coordinator, show an in-progress indicator on the list item, and surface success or error feedback to the user. Re-download action must invoke the file storage client to retrieve the existing file and trigger the system share/download sheet. All actions must be accessible and provide screen-reader announcements for state changes.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 4 - 323 tasks
Can start after Tier 3 completes
Implementation Notes
Use a local per-item loading state variable inside the BLoC/notifier — avoid storing loading state in the global list state to prevent unnecessary list rebuilds. Wrap the re-export and re-download handlers in a guard that checks `isLoading` before dispatching to prevent double-tap duplicate requests. Use SemanticsService.announce() for state transitions rather than relying solely on widget rebuilds, as screen readers may not detect rapid state changes. For file retrieval, call Supabase Storage's createSignedUrl with a short TTL and pass the URL to share_plus ShareFile — do not download the file to app storage unless sharing requires a local file path.
Coordinate with the audit logging backend: the Edge Function handling re-export should write to bufdir_export_audit_log; the mobile client does not write audit rows directly.
Testing Requirements
Widget tests (flutter_test): verify that tapping re-export button emits the correct event to the BLoC/notifier; verify loading state renders CircularProgressIndicator; verify success state restores button and shows feedback; verify error state shows error message and restores button. Mock ReportReexportCoordinator and Supabase Storage client. Integration tests: verify coordinator receives correct period ID; verify share_plus is invoked with a non-null file payload. Accessibility test: verify Semantics tree contains meaningful labels on all button states; verify live region announcements fire on state transitions.
The ReportSummaryMetricsWidget must display metrics as they were at time of submission, not recalculated from current data. If the metrics are not stored as a JSON snapshot in the history record at export time, the widget will either show wrong data or require a full re-aggregation on every list load.
Mitigation & Contingency
Mitigation: Ensure the Bufdir export pipeline (bufdir-report-export feature) writes a summary_metrics JSONB column in the history record at export time, containing total_activities, total_hours, and participants_reached. The UI widget reads only from this snapshot field — never from live aggregation queries.
Contingency: If snapshot data is missing for historical records (e.g., older exports before the column existed), display a 'Metrics not available for this report' placeholder in the widget rather than showing zeros or triggering a live aggregation that could return different figures.
Re-export can take several seconds (it runs the full generation pipeline). Without adequate progress feedback, coordinators may tap the button multiple times, triggering duplicate exports and duplicate history records.
Mitigation & Contingency
Mitigation: Disable the re-export button immediately on first tap and show an inline progress indicator on the list item. Guard against duplicate invocations at the service layer using an in-progress flag keyed by report ID. Display a loading state on the list item throughout the operation.
Contingency: If duplicate re-export records are created (e.g., due to a race condition), the history table will show multiple entries for the same original report — which is harmless but confusing. Add a deduplication UI hint ('Re-exported N times') and a backend guard that prevents more than one in-flight re-export for the same source record ID simultaneously.