high priority high complexity frontend pending frontend specialist Tier 1

Acceptance Criteria

The editor displays a two-column table: left column lists source fields from the external system, right column provides a dropdown or drag target for the internal data model field
Drag-and-drop mapping works: dragging a source field onto a target slot creates the mapping and provides visual drag feedback
Dropdown mapping works as an alternative for non-touch/accessibility scenarios: each row has a dropdown listing available internal fields
Already-mapped internal fields are visually marked as used and excluded from other rows' dropdown options to prevent duplicate mappings
Each mapping row shows per-row validation: a green checkmark for valid pairs, an amber warning for type-mismatched pairs (e.g., stringโ†’integer), and a red error for required fields left unmapped
Bufdir-specific override columns are clearly labelled with a 'Bufdir override' badge and accept a freetext column name for the Bufdir export format
A 'Clear Mapping' button per row removes the mapping and returns the internal field to the available pool
A 'Reset All' button resets all mappings to their last saved state after a confirmation dialog
The complete mapping is serializable to/from JSON and persists correctly to Supabase
The editor is fully keyboard-navigable: Tab moves between rows, Enter opens dropdowns, Escape closes them
The editor handles 50+ field rows without layout overflow or performance degradation
Unmapped required fields block the Save button and are highlighted in red with a summary count shown above the table

Technical Requirements

frameworks
Flutter
BLoC
Riverpod
apis
Supabase REST API โ€” integration_field_mappings table (read/write)
Supabase REST API โ€” integration_schema_discovery endpoint (fetch external system field list)
data models
FieldMapping
SourceField
TargetField
BufdirOverrideColumn
IntegrationConfiguration
performance requirements
Editor must render 50 mapping rows within 300ms
Drag-and-drop must respond within one frame (16ms) with no jank
Dropdown search/filter must debounce at 200ms and return results within 100ms
security requirements
Only admin-role users may modify field mappings โ€” enforce via RLS
Field names from external systems must be HTML-escaped before rendering to prevent injection
ui components
FieldMappingEditor (main widget)
MappingRow (source field + target dropdown/drag target)
BufdirOverrideBadge
MappingValidationIndicator (checkmark/warning/error icon)
DraggableFieldChip
DragTargetSlot
ResetAllDialog
MappingStatusSummaryBar

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

Use Flutter's `LongPressDraggable` and `DragTarget` for the drag-and-drop interaction. The drag handle should be on the source field chip, and each row's right side should be a `DragTarget`. For the dropdown alternative, use a `DropdownButtonFormField` or a custom `SearchableDropdown` that filters the available internal fields. Store mapping state in a `List` managed by a BLoC/StateNotifier.

Each entry: `{sourceFieldId, targetFieldId?, bufdirOverride?, validationStatus}`. Compute `validationStatus` reactively by comparing source field type to target field type from the schema. Implement a `FieldMappingRepository` that loads the external system's field schema from Supabase on widget initialization โ€” cache it in memory for the session. For the Bufdir override: treat it as an additional optional field per row, not a separate mapping; render it as a small `AppTextField` that appears when the row is expanded or when a 'Bufdir' toggle is active.

Avoid `setState` in the parent โ€” use fine-grained BLoC events (`MappingRowUpdated(rowIndex, targetFieldId)`) to update only affected rows.

Testing Requirements

Write flutter_test widget tests covering: (1) rendering 10 and 50 rows without overflow, (2) selecting a target via dropdown creates the mapping, (3) used fields are removed from other rows' dropdown options, (4) Bufdir override input appears and accepts text, (5) validation indicators show correct state for valid/warning/error rows, (6) Reset All dialog appears on button tap and restores prior state on confirm. Use `WidgetTester.drag` to test drag-and-drop mapping creation. Test keyboard navigation with `tester.sendKeyEvent`. Test serialization round-trip: create mappings in widget โ†’ extract JSON state โ†’ load into fresh widget โ†’ assert same mappings rendered.

Performance test with 50 rows using `benchmarkWidgetTester`.

Component
Field Mapping Editor
ui high
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.