# AP05 – Befundmodell mit Spec-/Diagnose-Trennung ## 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 einfach gelöscht, sondern **ersetzt** durch ein sauber geschnittenes Domain-Modell. Der alte Typ wird im Rahmen von AP09 eingefroren. ## Voraussetzungen - AP03 (Paketstruktur) ## Scope IN Folgende Typen im Paket `de.gecheckt.asv.domain.finding` (oder ähnliches Unterpaket von `domain`): ### `Severity` (Enum) - `ERROR` - `WARNING` - `HINT` ### `FindingKind` (Enum) - `SPEC` — Befund ist Teil des Spec-Urteils, beeinflusst `Verdict` - `DIAGNOSTIC` — zusätzliche Weiteranalyse, beeinflusst `Verdict` **nicht** ### `FindingLayer` (Enum) - `ARTIFACT` — äußeres Artefakt / Dateiebene - `TECHNICAL_STRUCTURE` — Service-Segmente, KKS, Transport - `DOMAIN_MODEL` — kanonisches Fachmodell (ASVREC/ASVFEH) ### `Finding` (Record) ```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, optional null String officialErrorCode, // offizieller Fehlercode, optional null String segmentType, // z.B. "UNB", optional Integer segmentIndex, // optional String fieldId, // z.B. "UNB_0020", optional String rawValue, // Rohwert, optional Integer position, // Byte-/Zeichenposition, optional String messageReference, // UNH 0062 bei Nachrichtenbezug, optional String germanMessage // deutscher Befundtext ) {} ``` Records mit vielen optionalen Feldern sind unschön — als Alternative ist eine reguläre Klasse mit Builder erlaubt, solange sie unveränderlich (`final`) ist und die gleichen Felder trägt. **Wichtig ist: unveränderlich und mit allen Metadaten aus `technik-und-architektur.md` Abschnitt „Befundarten".** ### `Verdict` (Enum) - `VALID` — keine Spec-ERROR-Befunde - `INVALID` — mindestens ein Spec-ERROR-Befund - `OPERATIONAL_ERROR` — Bedienfehler (Exit-Code 2) ### `ValidationReport` (Klasse) - unveränderlich - enthält: - `List findings` (alle Befunde, SPEC und DIAGNOSTIC gemischt, Reihenfolge erhalten) - Methode `Verdict computeVerdict()` — berücksichtigt **nur** `kind == SPEC` und `severity == ERROR` - Methode `List specFindings()` — filtert auf `kind == SPEC` - Methode `List diagnosticFindings()` — filtert auf `kind == DIAGNOSTIC` - Methode `boolean hasSpecErrors()` - Metadaten: `String fileName`, `Instant timestamp` - **invariant:** eine `DIAGNOSTIC`-Severity `ERROR` darf das Verdict **niemals** auf `INVALID` setzen. Dies ist per Unit-Test abzusichern. ### Unit-Tests - `ValidationReport` ohne Befunde → `Verdict.VALID` - `ValidationReport` mit einem SPEC-ERROR → `Verdict.INVALID` - `ValidationReport` mit einem DIAGNOSTIC-ERROR → `Verdict.VALID` (dieser Test ist kritisch!) - `ValidationReport` mit SPEC-WARNING → `Verdict.VALID` (nur ERROR zählt) - `specFindings()` / `diagnosticFindings()` filtern korrekt - Unveränderlichkeit: `findings`-Liste ist nicht modifizierbar ## Scope OUT - Integration des neuen Modells in den bestehenden Lauf (kommt in AP06) - Löschen oder Umbenennen der alten `validation.model.ValidationResult`-Klasse (das ist Teil von AP09) - Berichtserzeugung (Text-Rendering), Bericht-Format, Konsolenausgabe (kommt in AP07) - Architekturtest (kommt in AP10) ## Schritte 1. Branch `m1/ap05-befundmodell` 2. Paket `de.gecheckt.asv.domain.finding` anlegen 3. Enums und Klassen implementieren 4. Unit-Tests schreiben, mindestens die sechs oben genannten 5. `mvn clean verify` grün bekommen 6. Commit `M1-AP05: Befundmodell mit Spec-/Diagnose-Trennung` 7. Abschlussbericht schreiben ## Abnahmekriterien - Paket `domain.finding` enthält alle oben genannten Typen - **Der Test „DIAGNOSTIC-ERROR ergibt VALID" ist grün** und wird im Bericht explizit genannt - `ValidationReport.findings` ist unveränderlich (Test vorhanden) - alle Metadaten-Felder aus `technik-und-architektur.md` Abschnitt „Befundarten" sind im `Finding`-Typ vorhanden - `mvn clean verify` ist grün - keine Änderung an `validation.model.ValidationResult` (Altmodell) - Abschlussbericht liegt vor ## Rest-Risiken und offene Punkte - Wir haben jetzt zwei parallele Ergebnis-Typen: den alten `ValidationResult` und den neuen `ValidationReport`. Das ist **Absicht** bis AP09, wo die alte Logik sauber eingefroren wird. - Das Befundmodell ist bewusst **keine** Hierarchie (Datei → Schicht → Nachricht → Befund), sondern eine flache Liste mit Metadaten. Die hierarchische Berichtserzeugung passiert später auf Basis dieser Metadaten in M9. Für M1 genügt die flache Struktur. ## Bericht `docs/arbeitspakete/m1/berichte/AP05-bericht.md` nach `templates/ap-bericht.md`.