critical priority low complexity infrastructure pending backend specialist Tier 0

Acceptance Criteria

IntegrationTypeRegistry is implemented as an immutable Dart class with static const entries for all five system types: xledger, dynamics, cornerstone, consio, bufdir
Each registry entry contains: id (string key), displayName, description, requiredCredentialFields (list of field names), optionalCredentialFields, supportedCapabilities (enum list), and featureFlags (map)
Registry lookup by id returns the correct entry; lookup with unknown id returns null or throws a typed RegistryNotFoundException
requiredCredentialFields for Xledger includes at minimum: api_key, base_url, company_id
requiredCredentialFields for Dynamics includes at minimum: tenant_id, client_id, client_secret, resource_url
requiredCredentialFields for Cornerstone includes at minimum: api_key, subdomain
requiredCredentialFields for Consio includes at minimum: api_key, base_url
requiredCredentialFields for Bufdir includes at minimum: org_id, report_year, api_endpoint
All registry entries are accessible via IntegrationTypeRegistry.all() returning an unmodifiable list
Unit tests verify all five entries exist and contain non-empty requiredCredentialFields
No runtime mutation of registry data is possible (const or UnmodifiableListView patterns)

Technical Requirements

frameworks
Flutter
Dart
data models
IntegrationTypeEntry
IntegrationCapability (enum)
CredentialFieldDefinition
performance requirements
Registry lookup must be O(1) using a const Map keyed by integration type id
No database or network calls — entirely in-memory static data
security requirements
Registry must not store actual credential values — only field names and metadata
Credential field definitions must mark sensitive fields (e.g., client_secret, api_key) with isSensitive: true for downstream masking

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Integration Task

Handles integration between different epics or system components. Requires coordination across multiple development streams.

Implementation Notes

Implement as a pure Dart file with no Flutter widget dependencies — this makes it usable from both Flutter app and any Dart-only server-side code. Use a private const Map _registry as the backing store, exposed only via static methods. Define IntegrationCapability as a Dart enum with values like exportPayload, fetchRemoteSchema, testConnection, syncSchedule. Define CredentialFieldDefinition as a simple immutable class with fields: name, isSensitive, isRequired, description.

Keep this file focused — do not add validation logic here; that belongs in IntegrationConfigValidator (task-002). This registry is the single source of truth for what systems exist and what they need; every other component should import from here rather than hard-coding system names.

Testing Requirements

Unit tests using flutter_test. Write one test class per registry entry verifying: (1) entry exists by id, (2) displayName is non-empty, (3) requiredCredentialFields is non-empty and contains expected field names, (4) all declared capabilities are valid enum values, (5) no duplicate field names within an entry. Add a registry-level test asserting all five entries are present in IntegrationTypeRegistry.all(). Add a negative test: lookup('unknown_type') returns null or throws RegistryNotFoundException.

Target 100% branch coverage for the lookup method.

Component
Integration Type Registry
infrastructure low
Epic Risks (3)
medium impact high prob technical

Each of the five external systems (Xledger, Dynamics, Cornerstone, Consio, Bufdir) has a different authentication flow, field schema, and error format. Forcing them into a uniform adapter interface may require compromises that result in leaky abstractions or make the adapter contract too complex to maintain.

Mitigation & Contingency

Mitigation: Design the IntegrationAdapter interface with a loose invoke() payload rather than a typed one, allowing each adapter to declare its own input/output schema. Use integration type metadata in the registry to document per-adapter quirks. Build Xledger first as the most documented API, then adapt the interface based on learnings.

Contingency: If the uniform interface cannot accommodate all five systems, split into two interface tiers: a simple polling/export adapter and a richer bidirectional adapter, with the registry declaring which tier each system implements.

medium impact high prob dependency

Development and testing of the Cornerstone and Consio adapters depends on NHF providing sandbox API access. If credentials or documentation are delayed, these adapters cannot be validated, blocking the epic's acceptance criteria.

Mitigation & Contingency

Mitigation: Implement Xledger and Dynamics adapters first (better-documented, sandbox available). Create a mock adapter for Cornerstone/Consio using recorded API responses for CI testing. Proactively request sandbox access from NHF at project kickoff.

Contingency: Ship the epic with Cornerstone/Consio adapters in a 'stub' state (connectivity test returns a simulated success, invoke() is not production-wired) and gate the NHF integration behind a feature flag until real API access is obtained.

medium impact medium prob scope

Real-world field mappings may include nested transformations, conditional logic, and data type coercions (e.g., Norwegian date formats, currency rounding rules) that the Field Mapping Resolver's initial design does not accommodate, requiring scope expansion mid-epic.

Mitigation & Contingency

Mitigation: Gather actual field mapping examples from Blindeforbundet (Xledger) and HLF (Dynamics) before designing the resolver. Identify the most complex transformation required and ensure the resolver design handles it. Limit Phase 1 to direct field renaming and format conversion only.

Contingency: If complex transformations are required, implement a simple expression evaluator (e.g., JSONata or a custom mini-DSL) as an extension point in the resolver, delivering basic mappings first and complex ones in a follow-up task.