critical priority high complexity testing pending testing specialist Tier 5

Acceptance Criteria

Test setup: 10 approved claims seeded in test database — 5 for Blindeforbundet (Xledger) and 5 for HLF (Dynamics), all for the same reporting period
First export run (Xledger / Blindeforbundet): triggered successfully, payload contains exactly 5 claims, export run record created in repository with correct metadata
First export run (Dynamics / HLF): triggered successfully, payload contains exactly 5 claims, export run record created with correct metadata
Second export run (same period, same orgs): Double-Export Guard filters all previously exported claims — both runs return empty batches without error
Xledger payload structure validated: CSV output matches Xledger import specification (correct columns, delimiter, encoding)
Dynamics payload structure validated: JSON output matches Dynamics 365 API contract (correct property names, types, nesting)
Organisation isolation verified: Blindeforbundet export run does not affect HLF claim state and vice versa
Export run records persisted in test database are readable by the Export Run Repository and contain: org_id, period, exporter_type, claim_count, run_timestamp, status=completed
Test uses a local Supabase test instance with RLS policies enabled — tests pass only if RLS is correctly scoped
Test teardown removes all seeded data — no test data leaks between test runs
Full test suite completes in under 120 seconds on a standard development machine

Technical Requirements

frameworks
flutter_test
Supabase local development stack (supabase start)
apis
Supabase PostgreSQL 15 (local test instance)
Supabase Edge Functions (Deno) — local emulation for mark operation
data models
activity
activity_type
annual_summary
bufdir_export_audit_log
claim_event
assignment
performance requirements
Full E2E test suite must complete in under 120 seconds
Each individual export run trigger must complete in under 10 seconds in the test environment
Database seed and teardown operations must complete in under 5 seconds
security requirements
Test must verify RLS enforcement: a JWT scoped to org-A cannot retrieve org-B export run records
Supabase service role key used only in test setup/teardown (seeding), never in the code paths under test
Test database credentials stored in .env.test — never committed to version control
All test organisation IDs must be synthetic UUIDs, never production IDs

Execution Context

Execution Tier
Tier 5

Tier 5 - 253 tasks

Can start after Tier 4 completes

Implementation Notes

Structure the test file in three phases: (1) Seed phase — helper functions that insert test organisations, test users, and test approved claims using the Supabase admin client; (2) Execute phase — invoke the RunExportPipelineUseCase for each exporter type using a real (not mocked) pipeline with real guard and real repository connected to the local Supabase; (3) Assert phase — query the database directly to verify claim state, export run records, and payload content. The concurrency/idempotency test (re-triggering the same period) is the highest-value test in this suite — it validates the core business invariant of the entire epic. Use a TestSupabaseClient helper that wraps the Supabase client with automatic organisation-scoped JWTs for test users, so each database call in the assertion phase is authenticated as the correct test user. Avoid sharing state between test cases via class-level variables — use local variables in each test() block to keep tests independent and debuggable.

Testing Requirements

Integration test suite using flutter_test with a real local Supabase instance (supabase CLI). Tests organised in a single E2E test file: export_pipeline_e2e_test.dart. Test lifecycle: setUpAll seeds test organisations, users, and approved claims; each test case is independent and uses its own claim IDs; tearDownAll removes all seeded data. Use Supabase's admin client (service role) only in setup/teardown helpers, never in test assertions.

Test assertions query the database directly via the test client to verify state — do not rely solely on return values from the pipeline. Include a dedicated RLS test case that attempts a cross-org query with a scoped JWT and asserts zero results returned. Run this suite in CI with supabase start as a prerequisite step.

Component
Double-Export Guard
service medium
Epic Risks (3)
high impact medium prob dependency

The Xledger CSV/JSON import specification may not be available in full detail at implementation time. If the field format, column ordering, encoding requirements, or required fields differ from assumptions, the generated file will be rejected by Xledger on first production use.

Mitigation & Contingency

Mitigation: Obtain the official Xledger import specification document from Blindeforbundet before starting XledgerExporter implementation. Build a dedicated acceptance test that validates a sample export file against all documented constraints.

Contingency: If the spec arrives late, implement a configurable column-mapping layer so that field order and names can be adjusted via configuration without code changes. Ship a file-based export that coordinators can manually verify before connecting to Xledger import.

high impact low prob technical

The atomic claim-marking transaction in Double-Export Guard could fail under high concurrency if two coordinators trigger an export for overlapping date ranges simultaneously, potentially allowing duplicate exports to proceed past the guard.

Mitigation & Contingency

Mitigation: Use a database-level advisory lock or a SELECT FOR UPDATE on the relevant claim rows within the export transaction to serialize concurrent exports per organization. Add an integration test that simulates concurrent export triggers.

Contingency: If locking proves problematic at the database level, implement an application-level distributed lock using a Supabase row in a dedicated export_locks table with an expiry timestamp and automatic cleanup on failure.

medium impact high prob integration

HLF's Dynamics portal API endpoint may not be available or documented in time for Phase 1, leaving DynamicsExporter unable to be validated against a real system and potentially shipping with an incorrect field schema.

Mitigation & Contingency

Mitigation: Design DynamicsExporter for file-based export first (CSV/JSON download), with the API push implemented behind a feature flag. Request a Dynamics test environment or sandbox from HLF as early as possible.

Contingency: Ship DynamicsExporter as a file export only for Phase 1. Phase the API push integration into a follow-on task once the Dynamics sandbox is available, using the same AccountingExporter interface with no breaking changes.