critical priority medium complexity backend pending backend specialist Tier 1

Acceptance Criteria

A required field with a null value produces exactly one ValidationIssue with severity 'error' and ruleClass 'completeness'
A required field with an empty string value produces exactly one ValidationIssue with severity 'error' and ruleClass 'completeness'
A required field with a whitespace-only string value produces a ValidationIssue (whitespace is treated as empty)
A required field with a valid non-empty value produces no ValidationIssue
An optional field with a null or empty value produces no ValidationIssue
The ValidationIssue message uses the human-readable label from the configurable lookup map, not the raw field key
When a field key is absent from the lookup map, the raw field key is used as a fallback (no exception thrown)
The lookup map is injectable at construction time to support per-organization customization
The evaluator class is stateless: calling it multiple times with the same input produces identical output
The evaluator operates on a single BufdirReportSectionModel and returns a List<ValidationIssue>
No Flutter SDK imports are present in the evaluator class — pure Dart only

Technical Requirements

frameworks
flutter_test (for testing only)
Dart
data models
BufdirReportSectionModel
ValidationIssue
BufdirFieldLabelMap
performance requirements
Evaluation of a single section with 20 fields completes in under 1ms
No heap allocations beyond the returned list during evaluation
security requirements
Field values must not be logged — they may contain sensitive personal data (PII)
Lookup map must not expose internal field key naming conventions in error messages to end users

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Define a sealed class hierarchy for ValidationIssue if not already done in task-001 (severity as enum: error, warning, info; ruleClass as String or enum). The lookup map type should be Map injected via constructor: const CompletenessRuleEvaluator({required Map fieldLabels}). Use a simple extension method or static helper isBlankOrNull(dynamic value) → bool to centralise the null/empty/whitespace check — reuse this in later evaluators. Avoid using dynamic where possible; prefer typed accessors on BufdirReportSectionModel.

The class should implement an abstract RuleEvaluator interface defined in task-001 so the orchestrator (task-005) can treat all evaluators uniformly via polymorphism.

Testing Requirements

Unit tests using flutter_test (dart:test). Test class: CompletenessRuleEvaluatorTest. Required scenarios: (1) null value on required field → error issued, (2) empty string on required field → error issued, (3) whitespace-only string on required field → error issued, (4) valid value on required field → no issue, (5) null value on optional field → no issue, (6) human-readable label used in message when key present in map, (7) raw key used as fallback when key absent from map, (8) multiple required fields with multiple nulls → one issue per field, (9) section with zero required fields → empty list returned. Minimum 90% line coverage on evaluator class.

No mocking of Supabase or Flutter required — pure unit tests.

Component
Bufdir Field Validation Service
service medium
Epic Risks (2)
medium impact medium prob scope

The exact minimum threshold values required by Bufdir guidelines (e.g., minimum participant counts per section) may not be formally documented in machine-readable form. If thresholds must be researched or negotiated during implementation, the validation service will be delayed and may launch with incomplete rules, reducing its effectiveness.

Mitigation & Contingency

Mitigation: Compile threshold rules from the Bufdir reporting guidelines PDF before sprint start. Store rules in a separate configuration file (not hardcoded in the service class) so they can be updated without a service rewrite. Treat unknown thresholds as 'no minimum' to avoid false errors.

Contingency: Launch with completeness and anomaly validation only, shipping threshold compliance rules as a follow-on config update once rules are confirmed with Bufdir. Flag this as a known limitation in the coordinator help text.

high impact low prob technical

BufdirPreviewService coordinates three async operations (fetch aggregated data, map structure, run validation). Race conditions or partial failures in this chain could produce an inconsistent preview model — e.g., a model with field values but no validation results — which would silently mislead coordinators into thinking the report is clean.

Mitigation & Contingency

Mitigation: Model the orchestration as a single BLoC/Cubit state machine with explicit states (Loading, Loaded, Error) and ensure validation is always run atomically after mapping, never in parallel. Write integration tests that simulate network failure at each step of the chain.

Contingency: If a partial failure state reaches production, detect it via the missing validation summary field in the preview model and show a full-screen error state rather than an incomplete preview, prompting the coordinator to retry.