medium priority low complexity frontend pending frontend specialist Tier 3

Acceptance Criteria

Integration Configuration Dashboard shows a Design System v3 empty state (illustration + heading + CTA button 'Add Integration') when the integration list is empty
Integration Configuration Dashboard shows a Design System v3 error state (error icon + human-readable message + 'Retry' button) when the API fetch fails; pressing Retry re-triggers the data fetch
Field Mapping Editor shows an empty state (icon + message 'No source fields available for this integration type') when the returned source field list is empty; no mapping rows are rendered
Credential Management Form shows an inline error banner (not a modal) below the 'Test Connection' button when a network failure occurs during connection test, with message 'Connection test failed. Check your network and credentials.'
All empty and error states use only CSS classes and design tokens defined in Design System v3 — no inline styles
Error messages are user-friendly and do not expose internal error codes or stack traces to the UI
All states are accessible: error/empty state containers have appropriate ARIA roles (via Flutter Semantics widgets) and are reachable by screen readers
Retry and CTA actions are keyboard/switch-accessible (focusable, activatable without touch)

Technical Requirements

frameworks
Flutter
BLoC or Riverpod for state management
apis
Supabase REST (for retry logic triggering re-fetch)
data models
IntegrationConfig
FieldMapping
performance requirements
Empty/error state widgets must render in a single frame with no async operations blocking display
security requirements
Error messages shown in UI must not expose API error responses, HTTP status codes, or internal identifiers directly — log those to the console only
ui components
EmptyStateWidget (reusable Design System v3 component)
ErrorStateWidget (reusable Design System v3 component)
InlineErrorBanner
RetryButton

Execution Context

Execution Tier
Tier 3

Tier 3 - 413 tasks

Can start after Tier 2 completes

Integration Task

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

Implementation Notes

Create reusable EmptyStateWidget and ErrorStateWidget components if they do not already exist in the shared widget library, parameterised with icon, heading, body text, and an optional action button callback. Do not duplicate empty/error UI per screen — use these shared widgets. For the connection-test error in CredentialManagementForm, manage error visibility with a local bool in a StatefulWidget or a dedicated sub-state in the form's BLoC/Riverpod notifier; do not route this through the global error handler. Ensure the Retry button in the Dashboard re-dispatches the load event to the BLoC/provider rather than calling the service directly from the widget.

Testing Requirements

Write widget tests for each error/empty state: (1) seed the relevant BLoC/provider with an empty-data state and assert the empty state widget is visible; (2) seed with an error state and assert the error widget and Retry button are visible; (3) simulate tapping Retry and assert the fetch event is dispatched. Tests should use mocktail to simulate the failed network call for the connection-test banner scenario.

Epic Risks (4)
medium impact high prob technical

The multi-step Integration Setup Wizard must render different credential fields, field mapping targets, and validation rules depending on the selected integration type. If the type-specific branching logic is implemented as conditional widget trees rather than driven by the Integration Type Registry, the wizard becomes unmaintainable and adding new integration types requires UI code changes.

Mitigation & Contingency

Mitigation: Design the wizard to be metadata-driven from the Integration Type Registry from day one. Credential form fields, required field validation, and mapping target lists are all fetched from the registry, not hardcoded in widgets. Implement one integration type end-to-end first (Xledger) to validate the pattern before building the others.

Contingency: If the metadata-driven approach proves too complex for the initial delivery, implement Xledger and Dynamics as hardcoded wizard variants and create a registry-driven refactor as a follow-up technical debt ticket with a fixed deadline.

medium impact medium prob dependency

The Excluded Features Configuration Panel must wire directly into the feature flag system to suppress HLF app features. If the feature flag system does not yet expose a writable admin interface, this panel cannot save its configuration, blocking the HLF-specific acceptance criteria.

Mitigation & Contingency

Mitigation: Verify that the Organization-scoped Feature Flags feature (a declared dependency) exposes a Dart API for programmatic flag writes before starting this panel. Coordinate with the feature flags team to ensure the write API is available. If needed, schedule this panel as the last item in the epic.

Contingency: If the feature flag write API is unavailable at implementation time, store excluded features in the integration's JSONB settings column and wire them into a local feature flag provider that merges database state with the standard flag system at app startup.

high impact medium prob scope

The Field Mapping Editor's usability for non-technical org admins is high-risk. If the visual mapping interface is confusing, admins will configure incorrect mappings that cause silent data corruption in accounting exports — a serious financial risk discovered only at month-end reconciliation.

Mitigation & Contingency

Mitigation: Conduct usability testing with at least one admin user from Blindeforbundet on the field mapping editor prototype before full implementation. Provide descriptive labels and sample data values for all fields. Add a 'test mapping' preview that shows a transformed sample record before saving.

Contingency: If usability testing reveals the visual editor is too complex, implement a simplified list-based mapping editor (select app field → select external field, one row at a time) as a fallback, deferring the drag-and-drop visual editor to a future iteration.

medium impact medium prob technical

The Credential Management Form's masked fields and connection-test flow may conflict with screen reader requirements — VoiceOver and JAWS must be able to navigate the form, understand which fields are already configured, and receive feedback on connection test results without exposing credential values in accessible text.

Mitigation & Contingency

Mitigation: Design accessible semantics labels for masked fields (e.g., 'API key: configured, last 4 characters: abcd') from the start. Use Flutter's Semantics widget to provide screen-reader-specific text that differs from visual display. Test with VoiceOver on iOS and TalkBack on Android during development, not only at QA.

Contingency: If accessibility conflicts with security requirements for the credential form, implement a separate 'accessibility mode' flow where credential configuration is done through a separate confirmation step that provides more explicit semantic feedback without risk of value exposure.