critical priority low complexity frontend pending frontend specialist Tier 0

Acceptance Criteria

ExportScope enum is defined with exactly three values: localChapter, region, national (camelCase Dart convention)
ExportScopeState class is immutable (using @immutable or const constructors) and holds: selectedScope (ExportScope?), permittedScopes (List<ExportScope>), and isLoading (bool) fields
ExportScopeNotifier extends StateNotifier<ExportScopeState> and provides: selectScope(ExportScope), setPermittedScopes(List<ExportScope>), and reset() methods
Riverpod exportScopeProvider is defined as a StateNotifierProvider<ExportScopeNotifier, ExportScopeState>
ExportScope has a toJson() method returning a String key compatible with the BufdirExportRequest payload contract (e.g., 'local_chapter', 'region', 'national')
ExportScope has a fromJson(String) factory that correctly parses all three values and throws an ArgumentError for unknown values
ExportScopeState has copyWith() method with all fields optional for immutable state updates
Unit tests verify: initial state has null selectedScope and empty permittedScopes, selectScope updates state correctly, toJson/fromJson round-trip for all three values
File is placed in lib/features/bufdir_export/models/ following the project's feature-first structure

Technical Requirements

frameworks
Riverpod
Flutter
flutter_riverpod package
data models
ExportScope
ExportScopeState
BufdirExportRequest (interface contract reference)
performance requirements
State updates must be synchronous and complete within a single frame
Provider must not cause unnecessary rebuilds — use select() pattern where appropriate in consuming widgets
security requirements
ExportScope values must be validated on deserialisation — never silently accept unknown scope strings
Selected scope must be cleared on user logout via provider disposal or explicit reset

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Follow the existing Riverpod patterns in the codebase — check how other providers are structured (e.g., auth provider, activity provider) and mirror the file/naming conventions. Use freezed or manual copyWith depending on what the rest of the project uses. Keep ExportScope as a simple Dart enum without additional package dependencies. The toJson string values ('local_chapter', 'region', 'national') must exactly match what the Supabase edge function expects in the BufdirExportRequest payload — confirm this contract with the backend task owner before finalising.

Export all public symbols from a barrel file at lib/features/bufdir_export/models/export_scope.dart.

Testing Requirements

Write unit tests using flutter_test. Test ExportScopeNotifier state transitions: (1) initial state is correct, (2) selectScope transitions selectedScope, (3) setPermittedScopes updates the list, (4) reset() returns to initial state. Test ExportScope serialisation: toJson() and fromJson() round-trip for all three values, fromJson throws on unknown string. Use ProviderContainer in tests to avoid Flutter widget binding.

Aim for 100% line coverage of the models and notifier files.

Component
Export Scope Selector
ui medium
Epic Risks (2)
high impact medium prob security

The scope selector must accurately reflect each coordinator's access rights within the org hierarchy. If a coordinator can select a scope broader than their authorised access, the edge function's RLS enforcement must catch the attempt — but a permissive RLS policy or a bug in the scope resolver could allow unauthorised data to be exported.

Mitigation & Contingency

Mitigation: Implement permission enforcement at two independent layers: (1) the scope selector only renders options permitted by the user's role record, and (2) the edge function re-validates the requested scope against the user's JWT claims before executing any queries. Write integration tests that attempt to invoke the edge function with a scope beyond the user's permissions and assert rejection.

Contingency: If a permission bypass is discovered post-launch, immediately disable the export feature via the org-level feature flag while the fix is deployed. Review all audit records for exports that may have included out-of-scope data and notify affected organisations.

medium impact medium prob technical

The export workflow has 7+ discrete states (idle, scope selected, period selected, preview loading, preview ready, confirming, exporting, complete, failed) and several conditional transitions. An incomplete BLoC state machine could allow duplicate submissions, stale preview data to be confirmed, or error states to be unrecoverable without a restart.

Mitigation & Contingency

Mitigation: Model the state machine explicitly as a sealed class hierarchy before coding. Review the state diagram against all user story acceptance criteria. Write bloc unit tests for every valid and invalid state transition, including the happy path and all documented error states.

Contingency: If the BLoC grows too complex to test reliably, decompose it into two cooperating blocs: one for configuration (scope + period selection) and one for execution (preview + confirm + export), linked by a coordinator object.