Integrate API client into export service routing
epic-bufdir-report-export-api-integration-task-007 — Wire the bufdir-api-client into the bufdir-export-service submission routing. When submission_mode is direct_api, call bufdir-api-client.submit() instead of the file generation path. Ensure the orchestration layer interface is unchanged, pass the canonical payload from bufdir-format-serializer to the client, and propagate the BufdirSubmissionResult back to the calling screen for confirmation display.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Handles integration between different epics or system components. Requires coordination across multiple development streams.
Implementation Notes
The routing seam in BufdirExportService should be a single private `_submitDirectApi(payload)` method alongside the existing `_submitFileBased(payload)` method — the public `submitReport()` method selects between them via the feature flag. Inject BufdirApiClient as a constructor parameter so the service is testable with a mock. Use a try/catch around the entire direct-API path and rethrow as a domain-level BufdirExportException so the BLoC never handles raw Dio or http errors. For the confirmation screen, extend the existing BufdirExportState with a new `submittedDirectApi` variant carrying the reference number — do not reuse the file-based success state as they have different confirmation UI requirements.
Write the audit log entry inside the service (not the BLoC) so it is guaranteed regardless of BLoC state.
Testing Requirements
Integration tests using a fake BufdirApiClient and fake BufdirExportService: (1) direct_api mode routes through API client and emits submittedDirectApi state with reference number, (2) file_based mode routes through file path and emits submittedFileBased state, (3) API client error propagates to failed state with correct error type, (4) audit log written on both success and failure paths. Widget test for confirmation screen: reference number rendered when present, error message rendered on failure state. End-to-end test against Supabase staging (optional, CI-gated).
Norse Digital Products has not yet completed API negotiations with Bufdir. If negotiations stall or Bufdir's API design diverges significantly from expectations, the API client may need substantial rework, or the epic may be blocked indefinitely.
Mitigation & Contingency
Mitigation: Implement the client against a locally defined stub of the expected Bufdir API schema. Isolate all Bufdir-specific schema mapping in a single adapter class so that changes to the actual API schema require changes in only one place. Keep the epic in 'interface-ready' status until real API credentials are available for integration testing.
Contingency: If API negotiations are not completed within the planned window, defer this epic without impact on any other epic — the PDF/CSV fallback path from Epics 1–4 delivers full standalone value. Mark the epic as blocked and resurface when negotiations conclude.
Bufdir API credentials stored in the application or edge function environment could be exposed through misconfigured secrets management, log leakage, or a compromised deployment pipeline, allowing unauthorised Bufdir submissions on behalf of the organisation.
Mitigation & Contingency
Mitigation: Store all Bufdir API credentials exclusively in Supabase Vault (or the integration credential vault component), never in client-side code or environment variables accessible to the Flutter app. Transmit credentials only from within the edge function, not from the Flutter client. Implement credential rotation support from the outset.
Contingency: If a credential leak is detected, immediately revoke and rotate the affected API credentials through Bufdir's credential management portal, audit submission logs for any unauthorised calls, and notify Bufdir's technical contact per the API agreement's security incident clause.