Metadata flags toggle section in form
epic-activity-type-configuration-admin-interface-task-006 — Implement the three boolean metadata flag controls inside ActivityTypeFormScreen as clearly labelled toggle switches with descriptive helper text: (1) travel_eligible — indicates travel reimbursement applies; (2) report_required — enforces post-session report submission; (3) reimbursement_trigger — marks activity as eligible for expense reimbursement. Group them under a 'Behaviour flags' section header using design token card layout. Wire each toggle to the Bloc and ensure WCAG 2.2 AA touch target sizing.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 5 - 253 tasks
Can start after Tier 4 completes
Implementation Notes
Use SwitchListTile.adaptive() to respect platform conventions (Cupertino switch on iOS, Material on Android) — check whether the project already uses .adaptive() elsewhere and match. Wrap the three SwitchListTiles in a Column inside a Card or design-token container; do not use a ListView.builder for only three items. Set the SwitchListTile's contentPadding using design token spacing constants to ensure consistent alignment with text fields above. The semantic label should be the full descriptive title string — e.g., 'Travel reimbursement applies, switch, on'.
Test with TalkBack/VoiceOver during development to confirm announcement quality. If isTravelEligible and isReimbursementTrigger are conceptually linked (travel implies reimbursement), consider adding a one-line informational note — but do NOT automatically change one toggle when the other is toggled without explicit product sign-off.
Testing Requirements
Write widget tests: (1) all three toggles render with correct title and subtitle text; (2) tapping isTravelEligible toggle dispatches ActivityTypeTravelEligibleChanged(true) then ActivityTypeTravelEligibleChanged(false) on second tap; (3) identical tests for isReportRequired and isReimbursementTrigger; (4) in edit mode with all flags true, all three toggles render in the ON state; (5) in creation mode, all three toggles render in the OFF state; (6) orientation change preserves all toggle states via BLoC; (7) accessibility test using flutter_test's SemanticsController confirms each toggle has a meaningful semantic label and correct checked/unchecked state announced. Target 100% branch coverage for toggle interaction handlers.
The Bufdir reporting category list is defined externally by Bufdir and may change between reporting years. If the dropdown in ActivityTypeFormScreen is hardcoded, existing activity type mappings could become invalid after a Bufdir schema update, breaking export validation for all organisations.
Mitigation & Contingency
Mitigation: Store the valid Bufdir category list in a Supabase configuration table (bufdir_categories) rather than as a Dart constant, so it can be updated by an admin without a mobile app release. Load the list in the form screen via a lightweight repository call cached locally.
Contingency: If the Bufdir category list cannot be externalised before the admin screen ships, expose a manual override field that allows coordinators to enter a raw Bufdir category code as a fallback, and schedule the configuration table migration as a follow-up task.
Reusing ActivityTypeFormScreen for both creation and editing requires careful Riverpod provider scoping. If the form provider is not properly reset between navigation events, stale values from a previously edited type may pre-populate a new creation form, leading to incorrect data being saved.
Mitigation & Contingency
Mitigation: Scope the form state provider to the route using Riverpod's autoDispose modifier, ensuring the state is torn down when the screen is popped. Write a widget test that navigates to edit type A, pops, navigates to create new, and asserts all fields are empty.
Contingency: If provider scoping proves complex with the current router setup, fall back to separate widget implementations for create and edit that share a common form widget but maintain independent provider instances.
Archiving an activity type must not break historical Bufdir export queries that filter activities by type. If the export pipeline performs an INNER JOIN against only active activity types, archived types will cause historical activities to be silently excluded from exports, producing incorrect reporting data.
Mitigation & Contingency
Mitigation: Audit all downstream query builders (Bufdir export, stats aggregation) before shipping the archive feature to confirm they join against all activity types regardless of is_active status. Add an integration test that archives a type, then asserts historical activity records for that type still appear in export queries.
Contingency: If a downstream query is discovered to filter on is_active post-launch, apply a targeted Supabase view fix that unions active and archived types for export contexts without requiring a mobile app update.