high priority medium complexity backend pending backend specialist Tier 7

Acceptance Criteria

IntegrationConfigValidator calls adapter.getCapabilities() to retrieve the AdapterCapabilities object before running field/mapping/credential rules
Required credential scopes from AdapterCapabilities.requiredCredentialScopes are checked against the provided credentials — any missing scope produces a CREDENTIAL_SCOPE_MISSING error
Required field mappings from AdapterCapabilities.requiredMappings are checked against the provided mapping blob — any missing mapping produces a MAPPING_REQUIRED error with the field name
Optional vs required classification of mappings is entirely driven by AdapterCapabilities — no per-adapter if/else logic exists in the validator class itself
If getCapabilities() fails or returns null, validation returns a CAPABILITIES_UNAVAILABLE error and does not proceed with capability-dependent rules
Capability-independent rules (e.g., sync schedule format) still run even when capabilities are unavailable
Adding a new adapter with new required fields does NOT require changes to the validator class — only the adapter's getCapabilities() implementation
The validator correctly handles adapters that declare zero required mappings (no false-positive errors)
Capability results are not cached across validation calls — each call fetches fresh capabilities to catch adapter updates
All validation errors produced by capability-driven rules include the adapter's integration type in the error context for debugging

Technical Requirements

frameworks
Dart
BLoC
Riverpod
apis
Adapter Registry getCapabilities() interface
AdapterCapabilities model (requiredCredentialScopes, requiredMappings, optionalMappings)
data models
AdapterCapabilities
RequiredCredentialScope
RequiredMapping
ConfigValidationError
IntegrationConfig
performance requirements
getCapabilities() call must be made at most once per validation invocation
Capability-driven validation rules must complete within 1 second after capabilities are fetched
If getCapabilities() does not respond within 3 seconds, treat as CAPABILITIES_UNAVAILABLE
security requirements
Credential scope validation must only check for the presence of scope keys — never log or compare credential values
Adapter capabilities must be fetched from the in-process registry (not an external network call) to avoid SSRF risk

Execution Context

Execution Tier
Tier 7

Tier 7 - 84 tasks

Can start after Tier 6 completes

Integration Task

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

Implementation Notes

The adapter-aware validation should be implemented as a dedicated private method `_validateAgainstCapabilities(IntegrationConfig config, AdapterCapabilities capabilities)` that takes the already-fetched capabilities as a parameter — this keeps it pure and testable without mocking async calls. Use a `try/catch` with `Future.timeout(Duration(seconds: 3))` around the getCapabilities() call and map any failure to a CAPABILITIES_UNAVAILABLE error entry. Structure validation in two phases: Phase 1 runs sync rules (schedule format, non-null checks); Phase 2 awaits getCapabilities() and runs capability-driven rules. Both phases' errors are collected and returned together.

Avoid using `is` type checks on specific adapter types inside the validator — this would re-introduce hardcoded per-system logic. A good code smell test: the validator file should have zero import references to Xledger, Dynamics, Cornerstone, Consio, or Bufdir adapter classes.

Testing Requirements

Unit tests using mock adapters with configurable getCapabilities() responses: (1) adapter requiring 2 credential scopes — both present passes, one missing fails with CREDENTIAL_SCOPE_MISSING, (2) adapter requiring 3 field mappings — all present passes, one missing fails listing the missing field, (3) adapter requiring zero mappings — no mapping errors produced, (4) getCapabilities() returning null produces CAPABILITIES_UNAVAILABLE error, (5) getCapabilities() throwing produces CAPABILITIES_UNAVAILABLE error (no propagation), (6) getCapabilities() timeout (simulated with Future.delayed > 3s) produces CAPABILITIES_UNAVAILABLE error, (7) schedule validation error still appears even when capabilities are unavailable, (8) adding a mock adapter with different required fields correctly triggers different errors without changing validator code. Parameterize test cases across all five integration types (Xledger, Dynamics, Cornerstone, Consio, Bufdir) using test fixtures. Target 90%+ line coverage.

Component
Integration Config Validator
infrastructure medium
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.