Define typed error models for Vipps and BankID API failures
epic-bankid-vipps-login-api-clients-task-001 — Create a shared typed error model layer covering all expected failure modes from both Vipps Login OAuth 2.0 and BankID assertion flows. Include network errors, OAuth error codes (invalid_grant, access_denied, etc.), BankID-specific errors (session expired, assertion invalid), and environment-config errors. These types will be the contract between client components and the service layer.
Acceptance Criteria
Technical Requirements
Implementation Notes
Use Dart's sealed class feature (available since Dart 3.0) for exhaustive pattern matching at compile time. Define the hierarchy in lib/src/auth/errors/auth_failure.dart (or equivalent path under the auth domain). Example structure: sealed class AuthFailure { const AuthFailure(); } followed by final class NetworkTimeout extends AuthFailure { const NetworkTimeout(); } and so on. For variants that carry contextual data (e.g., oauthError carrying the raw code string), use a named parameter in the constructor.
For the Result type, either use a package like fpdart (Either in the same domain folder — do not pull in a new dependency if the project doesn't already use one; check existing dependencies first. Ensure the error type file has no imports from Flutter (dart:ui, package:flutter) — it must be a pure Dart file so it can be used in Edge Function Dart code if needed. Document the mapping from Vipps OAuth error response fields (error, error_description) to AuthFailure variants in a code comment for future maintainers.
Testing Requirements
Write Dart unit tests covering: (1) each sealed class variant can be instantiated with expected properties, (2) pattern matching (switch/when) over AuthFailure is exhaustive — verified by adding a new variant and confirming the compiler error, (3) message and detail fields do not contain NIN or phone number values in any variant's default factory, (4) const constructors are used for fixed variants (verify with identical() check). No widget tests needed for this task — pure model layer. Run dart analyze with zero warnings on the new files.
Norway has multiple BankID broker providers (e.g., Signicat, Criipto, Nets) with different integration contracts, pricing, and WebView behavior. If the broker is not selected and contractually agreed before implementation begins, the BankIDProviderClient may need to be rewritten after initial build.
Mitigation & Contingency
Mitigation: Define a minimal broker interface abstraction (session initiation, WebView URL generation, assertion validation) before writing any provider-specific code. Confirm broker selection with Norse Digital Products before starting this epic.
Contingency: If the broker changes after implementation, the abstraction layer allows replacing the provider-specific implementation behind the same interface with a targeted rewrite rather than a full redesign.
Android deep link handling with custom URI schemes can conflict with existing app links (HTTPS-based) or fail silently on certain Android versions if the intent filter is misconfigured, causing OAuth callbacks to never reach the app and leaving users stranded on the Vipps or BankID page.
Mitigation & Contingency
Mitigation: Use HTTPS app links (Android App Links) rather than custom URI schemes where possible, as they are more reliable on modern Android. Test deep link receipt on Android 12+ explicitly during development, as this version changed intent flag requirements.
Contingency: Implement a polling fallback for Vipps (check auth status on app foreground) as a secondary callback mechanism if deep link receipt fails on specific Android configurations.
Vipps Login has a separate test environment (mt2.vipps.no) that requires distinct test merchant credentials which must be applied for separately. If test credentials are delayed, integration testing of the VippsApiClient cannot proceed, blocking the entire authentication flow.
Mitigation & Contingency
Mitigation: Apply for Vipps test merchant credentials at the start of the project sprint, not when implementation begins. Use Vipps' publicly documented mock token responses for unit tests to decouple unit testing from live credentials.
Contingency: Implement the VippsApiClient with full mock injection support so all service-layer tests can run against a stub client while waiting for official test credentials.