Define ValidationIssue model and rule interfaces
epic-bufdir-report-preview-core-logic-task-001 — Create the core Dart data models for the validation layer: ValidationIssue (with severity enum: error/warning/info, fieldKey, humanReadableMessage, ruleClass enum: completeness/threshold/anomaly), ValidationResult (list of issues + overall pass/fail), and the abstract BufdirValidationRule interface. These types form the contract between the validation engine and all consumers.
Acceptance Criteria
Technical Requirements
Implementation Notes
Use Dart's built-in immutability patterns — all fields final, constructor const where possible. For == and hashCode, implement manually or use package:equatable if it is already in pubspec.yaml: `class ValidationIssue extends Equatable { ... @override List
ValidationResult.passed computation: `bool get passed => !issues.any((i) => i.severity == ValidationSeverity.error)` — warnings and infos do not block submission. BufdirValidationRule interface: keep the validate() signature generic (`Map
The barrel export file should be lib/features/bufdir/validation/models/bufdir_validation_models.dart.
Testing Requirements
Pure Dart unit tests (no flutter_test widgets needed): (1) ValidationResult.passed is false when any issue has severity=error; (2) ValidationResult.passed is true when all issues are warning or info; (3) ValidationResult.passed is true when issues list is empty; (4) ValidationIssue equality: two instances with identical fields are equal (==) and have same hashCode; (5) ValidationIssue.copyWith produces correct new instance; (6) BufdirValidationRule can be implemented as a concrete class in tests and validate() returns ValidationResult. All tests in test/bufdir/validation/ directory.
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.
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.