Wire ApprovalActionSheet to ApprovalWorkflowService
epic-expense-approval-workflow-bulk-and-action-task-010 — Connect ApprovalActionSheet confirmation actions to ApprovalWorkflowService for individual claim transitions. Pass approval decision and rejection comment to the service call, handle loading and error states within the sheet, close the sheet on success, and propagate error messages inline on failure without dismissing the sheet.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Use BlocConsumer in ApprovalActionSheet to react to state changes: listen block handles navigation (pop on success) and error announcements; builder block handles UI rendering. Pass the BLoC in via context (provided by parent screen's BlocProvider) rather than creating it inside the sheet — this allows the parent to react to success and refresh its own list. For the service layer, ApprovalWorkflowService.approveExpenseClaim should insert a ClaimEvent row via Supabase with the appropriate status transition and let a Postgres trigger or Edge Function handle the actual expense_claims status update — this keeps audit trail complete. Rejection comment max length enforcement: add inputFormatters: [LengthLimitingTextInputFormatter(1000)] to the comment field.
Testing Requirements
Unit test ApprovalWorkflowBloc: mock ApprovalWorkflowService and verify correct events produce correct state transitions (InProgress → Success, InProgress → Failure). Widget test ApprovalActionSheet: mock BLoC, pump ApprovalInProgress state and verify buttons are disabled and loader is visible; pump ApprovalSuccess and verify Navigator.pop is called; pump ApprovalFailure and verify error banner widget appears and sheet is still in tree. Integration test: use Supabase local emulator or test environment to verify actual ClaimEvent row is created with correct from_status/to_status on approve.
If a bulk approval batch partially fails (some claims approved, some failed), the UI must communicate which specific claims failed without overwhelming the coordinator. A poorly designed error display could cause coordinators to re-approve already-approved claims or miss claims that still need attention.
Mitigation & Contingency
Mitigation: Design the BulkApprovalResult display to show a clear summary (e.g., '14 approved, 2 failed') with a collapsible list of failed claims including their IDs and submitter names. Failed claims should remain selected in the queue so the coordinator can retry them individually.
Contingency: If the summary UI proves insufficient, add a dedicated 'bulk action history' sheet showing the last bulk operation result, accessible from the queue screen header.
If the app is backgrounded or the network drops while the coordinator has the ApprovalActionSheet open mid-decision, the typed comment could be lost and the transition state could be ambiguous, potentially causing a coordinator to believe they approved a claim that was never submitted.
Mitigation & Contingency
Mitigation: Persist the in-progress action sheet state (selected action + comment text) to a local draft store keyed on claim ID. On sheet re-open for the same claim, restore the draft. After confirmed submission, verify the resulting claim status from the server before dismissing the sheet.
Contingency: On network error during submission, display a persistent retry banner within the sheet rather than dismissing it, so the coordinator can resubmit without re-entering their comment.