high priority medium complexity integration pending integration specialist Tier 2

Acceptance Criteria

On panel mount, the component calls GET /organizations/{orgId}/integrations/{integrationId}/excluded-features and renders current suppression toggles accurately
Each feature toggle reflects the persisted state — no toggle defaults to a hardcoded value
When a toggle is changed, a PATCH or PUT call is dispatched immediately (or debounced ≤500ms) to persist the new suppression state
A loading indicator is shown per-toggle (or panel-level) while the save API call is in flight
On save success, a subtle success indicator (checkmark or toast) confirms persistence without blocking UI
On save failure, the toggle reverts to its previous state and an inline error message is displayed
The panel correctly handles an empty suppression list (all features enabled by default)
Suppression changes are scoped strictly to the current organization — cross-org contamination is impossible
The panel is usable while offline with a clear disabled state and offline notice
All toggles have accessible labels and role='switch' semantics for screen readers

Technical Requirements

frameworks
Flutter
BLoC
Riverpod
apis
Integration Config Service REST API — GET /organizations/{orgId}/integrations/{integrationId}/excluded-features
Integration Config Service REST API — PATCH /organizations/{orgId}/integrations/{integrationId}/excluded-features
data models
activity_type
performance requirements
Initial panel load must display persisted state within 1 second on good network
Toggle change must trigger save dispatch within 500ms of user interaction
Panel must not block navigation while save is in flight
security requirements
Organization ID derived from authenticated JWT claims — never from client-supplied input
Supabase RLS ensures suppression config rows are accessible only to admin/coordinator roles of the owning organization
API calls authenticated via Supabase session JWT
ui components
FeatureToggleRow widget (label + Switch + per-row loading indicator)
ExcludedFeaturesPanel container widget
Offline notice banner
SnackBar for transient save error feedback

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

Use a dedicated BLoC/Cubit (ExcludedFeaturesCubit) that holds the list of feature suppression entries as an immutable list. On toggle change, optimistically update local state then dispatch save; on failure roll back to previous snapshot. Debounce save calls by 300ms to handle rapid toggling without flooding the API. The feature list should be fetched from the backend rather than hardcoded — different organizations may have different available features based on their integration type (Xledger vs Dynamics).

Store the suppression config keyed by integration ID and organization ID in Supabase; apply RLS policy to the config table. Avoid storing any PII in the suppression config payload.

Testing Requirements

Write unit tests for the ExcludedFeaturesCubit covering: successful load → state populated, load failure → error state, toggle save success → state updated, toggle save failure → state reverted. Write widget tests verifying toggle reflects loaded state and reverts visually on save failure. Write integration tests against a Supabase local/staging instance to confirm read-write round-trip for suppression config. Test concurrent toggle changes (rapid taps) to ensure debounce logic prevents duplicate API calls.

Verify organization isolation by testing that org A's config cannot be read or written by org B's authenticated session.

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.