Define Bufdir API client interface contract
epic-bufdir-report-export-api-integration-task-001 — Design and document the abstract interface for the bufdir-api-client that is shared with the file-based export path. Define the SubmitReportRequest and SubmitReportResponse types, the BufdirSubmissionResult model including the reference number field, and the IExportSubmissionClient interface that both the API path and the file-based path implement. Ensure the orchestration layer requires no changes when switching between submission modes.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 0 - 440 tasks
Handles integration between different epics or system components. Requires coordination across multiple development streams.
Implementation Notes
Use Dart's sealed class pattern for SubmitReportResponse to get exhaustive pattern matching: sealed class SubmitReportResponse {} / class SubmitReportSuccess extends SubmitReportResponse { final BufdirSubmissionResult result; } / class SubmitReportFailure extends SubmitReportResponse { final BufdirSubmissionError error; }. This eliminates null checks in the orchestration layer. Define BufdirSubmissionError as an enum or sealed class covering the distinct failure modes. The interface design should anticipate that the Bufdir API negotiation is not complete — keep SubmitReportRequest flexible (Map
Consider adding a validate() method to SubmitReportRequest that checks required fields before submission to provide early validation. Place all types in lib/features/bufdir/data/models/bufdir_submission_models.dart and the interface in lib/features/bufdir/domain/repositories/i_export_submission_client.dart following clean architecture conventions.
Testing Requirements
Unit tests for the model classes only (no integration tests at this stage): (1) BufdirSubmissionResult serialization — assert toJson/fromJson round-trip preserves all fields including null referenceNumber; (2) SubmitReportRequest serialization round-trip; (3) BufdirSubmissionStatus enum coverage — assert all enum values are handled in a switch expression (exhaustiveness check via Dart sealed class or explicit default throw); (4) compile-time test: a mock implementation of IExportSubmissionClient compiles without error. No network calls in any tests for this task.
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.