high priority medium complexity testing pending testing specialist Tier 3

Acceptance Criteria

All Bufdir-required column headers are present and in the exact prescribed order in both Excel and CSV output
Norwegian characters (Γ¦, ΓΈ, Γ₯, Γ†, Ø, Γ…) are correctly encoded in CSV output (UTF-8 with BOM for Excel compatibility) and in Excel cell values
Participant counts are formatted as integers with no decimal places; hours are formatted as decimals with comma as separator (Norwegian locale)
Excel workbook structure contains the correct sheet name(s) as required by Bufdir template
CSV output uses semicolon as field delimiter matching Bufdir import expectations
Golden file comparison test passes against reference Bufdir template file for a canonical seed dataset
Empty activity list produces valid Excel/CSV with headers only, no errors thrown
Activities with maximum field lengths do not truncate or corrupt output
Test suite achieves 90%+ line coverage of BufdirExcelCsvGenerator class
All tests run without network or file-system dependencies (fully isolated)

Technical Requirements

frameworks
flutter_test
Dart test package
data models
BufdirActivityRecord
BufdirColumnMapping
BufdirExportConfig
performance requirements
Each unit test completes in under 500ms
Golden file comparison must not read from disk during CI β€” embed reference bytes as Dart constants or use testFixtures pattern
security requirements
No real participant PII used in test fixtures β€” use synthetic Norwegian names and national IDs
Golden reference files must not be committed with real organization data

Execution Context

Execution Tier
Tier 3

Tier 3 - 413 tasks

Can start after Tier 2 completes

Implementation Notes

BufdirExcelCsvGenerator likely wraps a Dart Excel/CSV library (e.g., excel package or csv package). Test at the public API boundary β€” call generate(List) and inspect the returned bytes or file handle rather than testing private helpers. For golden file tests, store reference .xlsx and .csv files under test/fixtures/bufdir/ and load them via rootBundle or File in test setup. Norwegian locale formatting: use NumberFormat from intl package configured with 'nb_NO' locale β€” verify the generator uses this and assert formatted strings in output cells.

For CSV BOM: assert output bytes start with [0xEF, 0xBB, 0xBF] when Excel-compatibility mode is enabled. Use a ColumnOrderValidator helper that extracts row 0 header values and compares against an ordered const list β€” this makes column-order failures self-documenting. Avoid mocking the Excel library itself; test integration of generator + library together.

Testing Requirements

Unit tests only β€” no external dependencies. Use flutter_test with fake data factories to construct BufdirActivityRecord instances. Implement golden file tests using dart:typed_data to compare byte-level output against committed reference files for both .xlsx and .csv formats. Cover: (1) happy path with 1, 10, and 100 activity records; (2) Norwegian character encoding roundtrip; (3) number formatting for counts and hours; (4) empty input; (5) single-activity edge case; (6) column order validation by header name comparison.

Use group() blocks to separate Excel and CSV concerns. Aim for 90%+ coverage on the generator class.

Component
Excel / CSV File Generator
infrastructure medium
Epic Risks (3)
high impact medium prob technical

NHF contacts can belong to up to five local chapters simultaneously. If the deduplication logic in the activity query service incorrectly attributes cross-chapter activities, organisations will either under-report or over-report to Bufdir, which could trigger grant clawback or compliance investigations.

Mitigation & Contingency

Mitigation: Implement deduplication using the existing multi-chapter membership service as the source of truth for chapter affiliation. Write test fixtures covering all known multi-chapter edge cases and validate outputs against manually prepared reference exports from NHF.

Contingency: If deduplication cannot be made deterministic for complex hierarchies before release, gate the export behind an org-level feature flag and require NHF to validate a preview export against their manual Excel before enabling in production.

medium impact medium prob dependency

Server-side Dart libraries for Excel generation are less mature than equivalents in Node.js or Python. The chosen library may lack support for Bufdir-required formatting features (merged cells, data validation, specific date formats), requiring significant workaround effort or a library switch mid-implementation.

Mitigation & Contingency

Mitigation: Evaluate the top two Dart xlsx libraries (excel, spreadsheet_decoder) against a Bufdir template sample file before committing. Identify all required formatting features and verify library support in a spike.

Contingency: If no Dart library meets requirements, implement the Excel generation as a Supabase Edge Function in TypeScript using the well-supported ExcelJS library, exposing it to the Dart backend via an internal RPC call.

medium impact medium prob integration

The attachment bundler must retrieve documents from Supabase Storage that were uploaded by the document attachments feature. If storage paths, RLS policies, or signed URL expiry have not been standardised across features, the bundler may fail to retrieve attachments at export time.

Mitigation & Contingency

Mitigation: Audit the document attachments feature's storage schema and RLS policies before implementing the bundler. Agree on a stable internal service-account access pattern for cross-feature storage reads.

Contingency: If cross-feature storage access cannot be made reliable, implement the bundler to include only attachments that can be retrieved successfully and produce a manifest listing any attachments that could not be bundled, rather than failing the entire export.