high priority medium complexity frontend pending frontend specialist Tier 1

Acceptance Criteria

Panel lists all suppressible app features with their display name, a brief description, and the specific overlap risk with the Dynamics portal
Each feature row has a toggle switch that reflects the current enabled/disabled state loaded from Supabase
Attempting to disable a feature shows a confirmation dialog explaining the consequence ('Users will no longer see [Feature Name]. This cannot be undone without re-enabling.') before the toggle is committed
Attempting to re-enable a previously suppressed feature also shows a confirmation dialog
On confirmation, the change is persisted to Supabase immediately; on cancellation, the toggle returns to its prior state
If the Supabase write fails, the toggle reverts to its prior state and an error snackbar is shown
Features that are non-suppressible (core features) are listed but rendered as disabled toggles with a tooltip explaining why they cannot be suppressed
Panel clearly labels this as HLF-specific configuration; a note explains the Dynamics portal coordination context
Changes take effect in the app within 60 seconds via Supabase Realtime or on next app launch
Panel is accessible: toggle labels announced by screen reader, confirmation dialogs are focus-trapped
Audit log entry is created in Supabase for every feature suppression or re-enablement (who, when, what)

Technical Requirements

frameworks
Flutter
BLoC
Riverpod
apis
Supabase REST API — organization_feature_flags table (read/write)
Supabase Realtime — subscribe to feature_flags changes for live propagation
Supabase REST API — audit_log table (insert)
data models
FeatureFlag
OrganizationFeatureConfig
AuditLogEntry
performance requirements
Feature flag changes must propagate to the app within 60 seconds via Supabase Realtime
Panel must load current feature states within 500ms
security requirements
Only HLF org_admin role may modify feature flags — enforce via RLS with organization_id check
All feature flag changes must create an audit log entry with user_id, timestamp, feature_id, old_value, new_value
Feature flag reads are organization-scoped — one org cannot see another's configuration
ui components
ExcludedFeaturesConfigPanel
FeatureFlagRow (name + description + overlap risk + toggle)
FeatureSuppressionConfirmDialog
NonSuppressibleFeatureRow (disabled toggle + tooltip)
AppToggleSwitch (design system)
OrganizationContextBanner (HLF-specific label)

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Integration Task

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

Implementation Notes

Define the list of suppressible features as a compile-time constant (e.g., `SuppressibleFeature` enum) with metadata: `displayName`, `description`, `overlapRisk`, `isSuppressible`. This prevents the list from being driven entirely by the database, which could allow suppression of core features. The `organization_feature_flags` table should have a row per `(organization_id, feature_id)` with a `is_enabled` boolean. On panel load, fetch all rows for the current org and merge with the compile-time feature list (features without a row default to enabled).

Use optimistic UI: flip the toggle immediately, persist in background, revert on error. The confirmation dialog should render the feature name prominently and clearly state the impact. Use `showDialog` with a `WillPopScope`-equivalent to prevent dismissal by tapping outside. Subscribe to Supabase Realtime on the `organization_feature_flags` channel filtered by `organization_id` to receive changes from other admin sessions.

Testing Requirements

Write flutter_test widget tests for: (1) all suppressible features render with toggles in correct initial state, (2) tapping a toggle opens the confirmation dialog, (3) cancelling the dialog reverts toggle state, (4) confirming the dialog calls the repository write method, (5) failed Supabase write shows error snackbar and reverts toggle, (6) non-suppressible features render with disabled toggles. Mock Supabase repository with both success and failure scenarios. Test that audit log write is called on every confirmation. Test that the HLF context banner is rendered.

Test accessibility: toggles have Semantics labels, dialog is focus-trapped.

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.