critical priority medium complexity testing pending testing specialist Tier 3

Acceptance Criteria

A single end-to-end test harness screen exists that exercises all Tier 0 components in their correct call sequence without mocking any Tier 0 component (mocks may only be used for external services beyond Tier 0 boundary)
GeneratedReportsRepository.createAuditRecord() is called and inserts a record in the test database that is verifiable by querying the generated_reports table
OrgHierarchyResolver.expandScope() correctly resolves a region-level scope to its full list of chapter IDs and the count matches seed data
ExportDataQueryBuilder returns a non-empty dataset for the test scope and period; row count matches expected seed count
BufdirCategoryMapper produces zero unmapped/null categories for all rows in the dataset
ExportStorageBucket client successfully writes a file to the Supabase Storage test bucket and the signed URL is non-null and accessible
FileDownloadHandler retrieves the file from the signed URL and invokes the platform share sheet (verified via a mock share delegate in test context)
ExportPeriodPicker renders with correct initial state, responds to user date selection, and emits the correct period value
ExportConfirmationDialog renders with correct scope/period summary and its confirm/cancel actions emit expected events
ExportProgressIndicator transitions through idle → loading → complete states in correct order during the full export flow
All 7 component green-light checks are documented in a sign-off checklist that is committed to the repository
No Tier 1 work item references a Tier 0 component that has not passed green-light — this is enforced by a CI gate check

Technical Requirements

frameworks
flutter_test
integration_test
Riverpod (for state in test harness)
BLoC (if any component uses BLoC)
Supabase Flutter client SDK
apis
Supabase REST API
Supabase Storage API
Platform share sheet API (via flutter_share or share_plus)
data models
GeneratedReport
AuditRecord
OrgHierarchy
ExportDataRow
BufdirCategory
ExportFile
ExportPeriod
performance requirements
Full Tier 0 flow (from scope selection to file download trigger) must complete in under 10 seconds in the test harness
Storage write + signed URL generation must complete in under 2 seconds
security requirements
Test harness must use a test-only Supabase project — never run integration verification against production
Signed URLs must expire after a short duration (e.g., 60 seconds) in test context
Audit record must capture the test user ID, not a null value
ui components
ExportPeriodPicker
ExportConfirmationDialog
ExportProgressIndicator

Execution Context

Execution Tier
Tier 3

Tier 3 - 413 tasks

Can start after Tier 2 completes

Implementation Notes

Create a `test/integration/tier0_green_light_test.dart` file as the canonical sign-off artifact. Structure the test with a setUp that seeds the test database and a tearDown that removes all seeded data and deletes test storage files. Use a TestHarnessScreen widget that renders ExportPeriodPicker, ExportConfirmationDialog, and ExportProgressIndicator in a Column for widget testing. For the data layer components (repository, resolver, query builder, mapper, storage), write sequential integration test steps that assert on intermediate state, not just the final output.

Document the green-light checklist as a markdown table in `docs/tier0-green-light-checklist.md` and update it with actual test run timestamps and results. This task is a blocking gate — do not mark complete until every check is genuinely green in CI.

Testing Requirements

Write a dedicated integration test harness screen (not shown in production navigation) that wires all Tier 0 components together. Use flutter_test WidgetTester for UI components. Write a structured green-light checklist test that runs each component check as a named test case using group() and test() blocks. Each check must produce a clear PASS/FAIL with a descriptive message.

Run the full suite in CI as a required check before any Tier 1 branch can merge. Include a smoke test that runs the entire export flow from scope selection through to file download in one test case. Ensure all tests are idempotent (can be re-run multiple times without leftover state).

Component
Generated Reports Repository
data low
Dependencies (10)
Implement the export period picker as a stateless Flutter widget that presents predefined period presets (Q1, Q2, Q3, Q4, full year, custom range) and a custom date range picker falling back to calendar input. Widget takes an onPeriodSelected callback and an initial value. Follows design token system for spacing, typography, and colours. No upstream service dependencies — can be built and widget-tested in isolation before backend is ready. epic-bufdir-report-export-foundation-task-009 Implement the export confirmation dialog as a stateless Flutter widget that displays a summary of the export parameters (period, scope, format, estimated record count) and presents confirm/cancel actions. Widget accepts an ExportSummary model, an onConfirm callback, and an onCancel callback. Must pass WCAG 2.2 AA contrast requirements and be fully navigable by screen reader. No backend calls inside the widget itself. epic-bufdir-report-export-foundation-task-010 Implement the export progress indicator as a stateless Flutter widget showing step-by-step export progress: querying data, aggregating, generating file, uploading, and ready. Widget takes a current ExportStep enum and optional percentage value, renders an animated progress bar with step labels, and displays an error state with retry option. Accessible via semantics labels for screen readers. Zero service dependencies for isolated development and testing. epic-bufdir-report-export-foundation-task-011 Build the file download handler that retrieves a signed URL from export storage and triggers the native device save/share sheet using the share_plus or open_file Flutter package. Implement downloadAndShare(signedUrl, fileName, mimeType) with progress callbacks and error states. Handle iOS share sheet and Android save-to-downloads separately. This is the final delivery mechanism that coordinators interact with after an export completes. epic-bufdir-report-export-foundation-task-008 Write unit tests for GeneratedReportsRepository covering: successful audit record creation, status update on completion and failure, filtering by org_id and date range, handling of Supabase errors with typed failures, and RLS enforcement (queries from foreign org return empty). Use flutter_test with a mocked Supabase client. Aim for 100% method coverage since this is the compliance audit trail. epic-bufdir-report-export-foundation-task-012 Write unit tests for ExportDataQueryBuilder with fixture datasets covering: single-chapter scope, multi-level hierarchy scope, date range boundary conditions, activities with missing activity_type_configuration entries, and empty result sets. Verify that the returned ExportDataSet contains correctly joined fields and no duplicate rows. Include a test with a 50-activity fixture matching known Bufdir expected output. epic-bufdir-report-export-foundation-task-013 Write unit tests for BufdirCategoryMapper covering: successful mapping of all known activity types to their Bufdir codes, warning emission for unmapped activity types, batch mapping preserving input order, null safety on missing configuration rows, and audit log entry creation for unmapped types. Include a fixture of activity_type_configuration rows matching the current Bufdir category schema version. epic-bufdir-report-export-foundation-task-015 Write integration tests against the real Supabase test environment verifying: coordinator can upload and download files for their own org_id, coordinator cannot access files under a different org_id path, signed URL expiry is enforced, and upload of oversized files returns the correct error. Run tests against the staging Supabase project to validate that bucket policies are correctly applied before any production deployment. epic-bufdir-report-export-foundation-task-016 Write unit tests for OrgHierarchyResolver covering: national-level scope expanding to all 1400 leaf IDs, region-level scope expanding to correct subset of chapters, single chapter returning only itself, circular reference detection and graceful handling, soft-deleted node exclusion, and caching behaviour on second call. Include a fixture representing NHF's 3-level hierarchy (national → region → chapter) to verify correctness before integration. epic-bufdir-report-export-foundation-task-014 Run integration tests for ExportDataQueryBuilder against the Supabase test database seeded with realistic activity data spanning multiple chapters in an NHF-like hierarchy. Verify that query results for a region-level scope include exactly the expected activity count, that category mappings are correctly applied, and that the query completes within 3 seconds for a 12-month period with 5000 activities. Document any slow query patterns for index optimisation. epic-bufdir-report-export-foundation-task-017
Epic Risks (3)
high impact medium prob technical

NHF's three-level hierarchy (national / region / chapter) with 1,400 chapters may have edge cases such as chapters belonging to multiple regions, orphaned nodes, or missing parent links in the database. Incorrect scope expansion would silently under- or over-report activities, which could invalidate a Bufdir submission.

Mitigation & Contingency

Mitigation: Obtain a full hierarchy fixture export from NHF before implementation begins. Write exhaustive unit tests covering boundary cases: single chapter, full national roll-up, chapters with no activities, and chapters assigned to multiple regions. Validate resolver output against a known-good manual count.

Contingency: If hierarchy data quality is too poor for automated resolution at launch, implement a manual scope override in the coordinator UI that allows the coordinator to explicitly select org units from a tree picker, bypassing the resolver.

medium impact high prob dependency

The activity_type_configuration table may not cover all activity types currently in use, leaving a subset unmapped at launch. Bufdir submissions with unmapped categories will be incomplete and may be rejected by Bufdir.

Mitigation & Contingency

Mitigation: Run a query against production activity data before implementation to enumerate all distinct activity type IDs. Cross-reference with Bufdir's published category schema (request from Norse Digital Products). Flag every gap as a known issue and build the warning surface into the preview panel.

Contingency: Implement a fallback 'Other' category bucket for unmapped types and surface a prominent warning in the export preview requiring coordinator acknowledgement before proceeding. Log unmapped types for post-launch cleanup.

high impact low prob security

Supabase RLS policies on generated_reports and the storage bucket must enforce strict org isolation. A misconfigured policy could allow a coordinator from one organisation to read another organisation's export files, creating a serious data breach with GDPR implications.

Mitigation & Contingency

Mitigation: Write RLS integration tests that attempt cross-org reads with explicitly different JWT tokens and assert that all attempts return empty sets or 403 errors. Include RLS policy review in the pull request checklist. Use Supabase's built-in policy tester during development.

Contingency: If a policy gap is discovered post-deployment, immediately revoke all signed URLs for affected exports, audit the access log for unauthorised reads, and issue a coordinated disclosure to affected organisations per GDPR breach notification requirements.