high priority low complexity frontend pending frontend specialist Tier 0

Acceptance Criteria

Panel renders four frequency options: Hourly, Daily, Weekly, and Custom Cron — selectable via segmented control or radio group
When Daily or Weekly is selected, a time-of-day picker (HH:MM) appears and is required before saving
When Custom Cron is selected, a validated text input field appears accepting standard 5-field cron expressions; invalid expressions show an inline error
A 'Trigger Manual Sync' button is present and enabled only when an integration is in 'active' status; it is disabled with tooltip explanation otherwise
Tapping 'Trigger Manual Sync' calls the appropriate Supabase Edge Function and shows a loading indicator during the call
On successful manual sync trigger, a success snackbar is shown with the timestamp of the triggered run
On failure, an inline error message is shown with the error reason returned by the backend
All inputs persist to and load from Supabase correctly; navigating away and back retains saved schedule
Panel is accessible: all controls have Semantics labels, touch targets ≥ 44dp, contrast ratios ≥ 4.5:1
Panel uses only design token colours and spacing — no hardcoded hex values or pixel literals

Technical Requirements

frameworks
Flutter
BLoC
Riverpod
apis
Supabase REST API — integration_configurations table (read/write sync_schedule field)
Supabase Edge Function — trigger-manual-sync
data models
IntegrationConfiguration
SyncSchedule
performance requirements
Panel must render within 300ms of navigation
Manual sync trigger must show loading state within 100ms of tap
security requirements
Only users with 'admin' or 'org_admin' role may access this panel — enforce via RLS on Supabase and route guard in Flutter
CSRF protection via Supabase JWT on all write operations
ui components
SyncScheduleConfigPanel (stateful widget)
FrequencySelector (segmented control)
TimeOfDayPicker
CronExpressionInput with validator
ManualSyncButton
AppButton (design system)
AppTextField (design system)

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Integration Task

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

Implementation Notes

Use a BLoC or Riverpod StateNotifier to manage form state — avoid putting business logic in the widget build method. Model the sync schedule as a sealed class or enum with associated data: `HourlySyncSchedule`, `DailySyncSchedule(TimeOfDay time)`, `WeeklySyncSchedule(int weekday, TimeOfDay time)`, `CustomCronSchedule(String expression)`. Serialize to/from a JSON map stored in the `sync_schedule` JSONB column in Supabase. For cron validation, use a simple regex covering the 5-field standard cron format; do not pull in a heavy cron library.

The manual sync trigger should be an optimistic call with error rollback — show loading immediately, revert UI state on error. This panel is a dependency for tasks 002–005, so define the shared `IntegrationAdminPage` scaffold (sidebar + content area layout) here so downstream tasks can slot their panels into it.

Testing Requirements

Write flutter_test widget tests covering: (1) each frequency option renders the correct secondary input, (2) invalid cron expressions show error and block save, (3) ManualSyncButton is disabled when status is not 'active', (4) successful trigger call shows snackbar, (5) failure response shows error. Mock Supabase calls using a fake repository. Write integration tests verifying round-trip persistence: set schedule → save → reload → assert schedule matches. Test on both small (360px) and large (768px) screen widths.

Component
Sync Schedule Configuration
ui low
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.