critical priority medium complexity integration pending integration specialist Tier 2

Acceptance Criteria

Tapping 'Test Connection' sends the current credential form values to the Integration Config Service test endpoint via Supabase Edge Function
During the test, the 'Test Connection' button is replaced by a loading spinner and the form fields are disabled to prevent modification mid-test
On success: a green banner appears showing 'Connection successful — {latency}ms' with the measured round-trip latency
On failure: a red banner appears showing 'Connection failed: {plain-language error message}' — technical stack traces are not shown to the admin
The Save/Next button in the wizard is disabled until at least one successful connection test has been completed for the current credential set
If the admin modifies any credential field after a successful test, the success state is cleared and the Save button is disabled again until re-tested
The connection test endpoint is called via Supabase Edge Function — credentials are never sent directly from the client to the external system
Network timeout after 15 seconds results in a timeout error banner, not a hung spinner
Retry is available immediately after a failed test without page reload
Test result (success/failure/timestamp) is stored in wizard state for inclusion in the final review screen

Technical Requirements

frameworks
Flutter
BLoC
Riverpod
apis
Supabase Edge Function: POST /functions/v1/integration-connection-test (body: {integration_type, credentials})
Integration Config Service REST API (internal)
performance requirements
UI must reflect loading state within one frame of button tap
Timeout threshold: 15 seconds maximum wait before surfacing timeout error
Latency measurement must be client-measured (time from request send to response received)
security requirements
Credentials transmitted only to Supabase Edge Function over TLS — never to external API directly from client
Edge Function uses service role key server-side; client authenticates with user JWT only
Credential values must not be logged or included in error messages returned to client
Connection test result (pass/fail) logged in integration audit trail server-side
ui components
ConnectionTestButton (with loading state)
ConnectionResultBanner (success/error variants)
CredentialFormFieldGroup (disabled state during test)

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Integration Task

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

Implementation Notes

Model the connection test as a sealed state in Riverpod: ConnectionTestState { idle, loading, success(int latencyMs), failure(String message), timeout }. Measure latency client-side with Stopwatch started before the HTTP call and stopped on response. Use Supabase's functions.invoke('integration-connection-test') method rather than raw http.post so the user JWT is automatically attached. The Edge Function should forward credentials to the target external API's health/auth endpoint and return {success: bool, latency_ms: int, error?: string}.

On the Flutter side, set a Future.timeout(Duration(seconds: 15)) to enforce the timeout threshold and map TimeoutException to ConnectionTestState.timeout. Track 'hasTestedSuccessfully' as a bool in wizard step state; reset it in a ValueNotifier listener whenever any credential field controller text changes. Avoid storing raw credential values in Riverpod state beyond the form's TextEditingControllers — pass them as a snapshot only when invoking the test.

Testing Requirements

Unit tests: CredentialTestBloc/Notifier — test idle → loading → success and idle → loading → failure state transitions; test that credential field change after success resets to idle. Widget tests: tap test button, assert loading spinner shown and form disabled; mock success response, assert green banner with latency text; mock failure, assert red banner with error message; modify field after success, assert banner cleared and Save button disabled. Integration test: full flow through wizard step with real Edge Function mock (or staging environment). Coverage target: 90% on state machine, 80% on widget states.

Component
Credential Management Form
ui medium
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.