high priority medium complexity backend pending backend specialist Tier 1

Acceptance Criteria

When prior-period value is null, no ValidationIssue is emitted regardless of current value (no false positives)
When current-period value is null and prior-period is non-null, a ValidationIssue is emitted if the effective change exceeds the threshold (null treated as 0 for current)
When both values are zero, no ValidationIssue is emitted (0% deviation)
When the percentage deviation is strictly less than the configured threshold, no ValidationIssue is emitted
When the percentage deviation equals the configured threshold, no ValidationIssue is emitted (at-threshold is acceptable)
When the percentage deviation exceeds the configured threshold, exactly one ValidationIssue is emitted with severity 'warning' and ruleClass 'anomaly'
The warning message includes the prior value, current value, and the computed percentage deviation (rounded to nearest integer)
The default deviation threshold is 50% and can be overridden via injected AnomalyConfig
The evaluator accepts current-section and prior-section as separate parameters — it does not fetch prior data itself
The evaluator is stateless and pure Dart with no Flutter SDK dependencies
Percentage deviation is computed as abs(current - prior) / abs(prior) * 100 when prior != 0; when prior == 0 and current > 0, treat as 100% increase

Technical Requirements

frameworks
Dart
data models
BufdirReportSectionModel
ValidationIssue
AnomalyConfig
performance requirements
Evaluation of a section pair with 30 numeric fields completes in under 2ms
security requirements
Prior-period values must not be logged — may include sensitive activity counts
Do not retain references to prior-period model after evaluation completes

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Keep the deviation formula consistent: when prior == 0 and current == 0, deviation = 0%; when prior == 0 and current != 0, deviation = 100% (special case to avoid divide-by-zero). Use (current - prior).abs() / prior.abs() * 100 for all other cases. Round to nearest integer for display: deviation.round(). The direction of change (increase vs decrease) should be determined by comparing current to prior and using 'increased' or 'dropped' in the message accordingly.

AnomalyConfig is a simple injectable class: class AnomalyConfig { final double deviationThresholdPercent; const AnomalyConfig({this.deviationThresholdPercent = 50.0}); }. This evaluator's evaluate() signature differs slightly from completeness/threshold because it requires both current and prior BufdirReportSectionModel — define a nullable priorSection parameter on the RuleEvaluator interface or use a subtype.

Testing Requirements

Unit tests using flutter_test. Test class: AnomalyDetectionRuleEvaluatorTest. Required scenarios: (1) null prior → no issue, (2) both zero → no issue, (3) deviation below threshold → no issue, (4) deviation at threshold → no issue, (5) deviation above threshold → warning with correct message, (6) current null + prior non-null + deviation > threshold → warning (null treated as 0), (7) prior zero + current > 0 → 100% increase triggers warning, (8) positive spike (increase) above threshold → warning, (9) negative drop (decrease) above threshold → warning, (10) custom threshold via injected AnomalyConfig applied correctly, (11) field present in current but absent in prior → skip (no false positive). Assert message content includes prior value, current value, and rounded percentage.

Minimum 90% line coverage.

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.