--- model: sonnet --- # AP05 – Befundmodell mit Spec-/Diagnose-Trennung > **Meilenstein:** M1 > **Vorgänger:** AP03, AP04 ✅ > **Nachfolger:** AP06, AP07, AP09 > **Grundlage:** `docs/specs/technik-und-architektur.md` v5, §§ „Ergebnis- und Befundmodell", „Befundarten", „Gültigkeitsentscheidung und Exit-Codes" > **Entscheidungsprotokoll:** `docs/arbeitspakete/m1/E00-entscheidungsprotokoll.md` ## Ziel Im Paket `domain` ein **stabiles Befundmodell** einführen, das von Anfang an zwischen **Spec-Urteil** (verbindliches Prüfurteil gemäß Spezifikation) und **diagnostischer Weiteranalyse** (zusätzliche, das Spec-Urteil nicht verändernde Hinweise) unterscheidet. Dieses Modell ist das **Herzstück** für alle nachfolgenden Meilensteine. Der bestehende Typ `de.gecheckt.asv.validation.model.ValidationResult` wird nicht geändert — er wird in AP09 eingefroren. ## Voraussetzungen - AP03 (Paketstruktur vorhanden) - AP04 (Logging-Adapter) ## Scope IN Folgende Typen im Paket `de.gecheckt.asv.domain.finding`: ### `Severity` (Enum) - `ERROR` - `WARNING` - `HINT` ### `FindingKind` (Enum) - `SPEC` — Befund ist Teil des Spec-Urteils, beeinflusst `Verdict` - `DIAGNOSTIC` — zusätzliche Weiteranalyse, beeinflusst `Verdict` **niemals** ### `FindingLayer` (Enum) - `ARTIFACT` — äußeres Artefakt / Dateiebene - `TECHNICAL_STRUCTURE` — Service-Segmente, KKS, Transport - `DOMAIN_MODEL` — kanonisches Fachmodell (ASVREC/ASVFEH) ### `Finding` (Record oder unveränderliche Klasse) Alle Pflichtfelder laut `technik-und-architektur.md` §„Befundarten": ```java public record Finding( FindingKind kind, // SPEC oder DIAGNOSTIC Severity severity, // ERROR/WARNING/HINT FindingLayer layer, // ARTIFACT/TECHNICAL_STRUCTURE/DOMAIN_MODEL String ruleId, // interne Regel-ID, nullable String officialErrorCode, // offizieller Spec-Fehlercode, nullable String segmentType, // z.B. "UNB", nullable Integer segmentIndex, // nullable String fieldId, // z.B. "UNB_0020", nullable String rawValue, // Rohwert, nullable Integer position, // Byte-/Zeichenposition, nullable String messageReference, // UNH 0062 bei Nachrichtenbezug, nullable String germanMessage // deutscher Befundtext, nicht nullable ) {} ``` Records mit vielen optionalen Feldern sind unschön — als Alternative ist eine reguläre unveränderliche Klasse mit Builder erlaubt, solange alle Felder vorhanden sind. ### `Verdict` (Enum) - `VALID` — keine SPEC-ERROR-Befunde - `INVALID` — mindestens ein SPEC-ERROR-Befund - `OPERATIONAL_ERROR` — Bedienfehler (Exit-Code 2), wird in AP08 genutzt ### `ValidationReport` (unveränderliche Klasse) ```java public final class ValidationReport { // Metadaten String fileName; Instant timestamp; // Befunde List findings; // unveränderlich // Kern-Methoden Verdict computeVerdict(); // NUR SPEC+ERROR zählt boolean hasSpecErrors(); List specFindings(); List diagnosticFindings(); // Factory für Bedienfehler (AP08) static ValidationReport operationalError(String fileName, String ruleId, String message); } ``` **Invariante:** `computeVerdict()` berücksichtigt **ausschließlich** Findings mit `kind == SPEC` und `severity == ERROR`. Ein `DIAGNOSTIC`-ERROR darf das Verdict **niemals** auf `INVALID` setzen. Dies ist per Unit-Test abzusichern. ### Unit-Tests (Mindestanforderung) 1. Leerer Report → `Verdict.VALID` 2. Ein SPEC-ERROR → `Verdict.INVALID` 3. **Ein DIAGNOSTIC-ERROR → `Verdict.VALID`** (dieser Test ist kritisch und muss explizit vorhanden sein) 4. SPEC-WARNING → `Verdict.VALID` (nur ERROR zählt) 5. `specFindings()` / `diagnosticFindings()` filtern korrekt 6. `findings`-Liste ist nicht von außen modifizierbar 7. `operationalError(...)` → `Verdict.OPERATIONAL_ERROR` ## Scope OUT - Integration des neuen Modells in den bestehenden Lauf (AP06) - Löschen oder Umbenennen der alten `ValidationResult`-Klasse (AP09) - Berichtserzeugung, Textrendering, Konsolenausgabe (AP07) - Architekturtest (AP10) ## Schritte 1. Paket `de.gecheckt.asv.domain.finding` anlegen 2. Enums `Severity`, `FindingKind`, `FindingLayer` implementieren 3. `Finding` implementieren 4. `Verdict` implementieren 5. `ValidationReport` implementieren 6. Unit-Tests schreiben — mindestens die sieben oben genannten 7. `mvn clean verify` grün bekommen 8. Abschlussbericht schreiben ## Abnahmekriterien - [ ] Paket `domain.finding` enthält alle genannten Typen - [ ] **Test „DIAGNOSTIC-ERROR ergibt VALID" ist grün** und im Bericht explizit genannt - [ ] `ValidationReport.findings` ist unveränderlich (Test vorhanden) - [ ] Alle Metadatenfelder aus `technik-und-architektur.md` §„Befundarten" sind im `Finding`-Typ vorhanden - [ ] `operationalError(...)` Factory-Methode existiert - [ ] Keine Änderung an `ValidationResult` (Altmodell) - [ ] `mvn clean verify` grün - [ ] Abschlussbericht unter `docs/arbeitspakete/m1/berichte/AP05-bericht.md` ## Rest-Risiken und offene Punkte - Zwei parallele Ergebnistypen (`ValidationResult` alt, `ValidationReport` neu) sind bis AP09 Absicht. - Das Befundmodell ist bewusst eine **flache Liste** mit Metadaten, keine Hierarchie. Die hierarchische Berichtserzeugung kommt in M9. ## Bericht `docs/arbeitspakete/m1/berichte/AP05-bericht.md` nach `docs/arbeitspakete/m1/templates/ap-bericht.md`.