139 lines
5.4 KiB
Markdown
139 lines
5.4 KiB
Markdown
---
|
||
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<Finding> findings; // unveränderlich
|
||
|
||
// Kern-Methoden
|
||
Verdict computeVerdict(); // NUR SPEC+ERROR zählt
|
||
boolean hasSpecErrors();
|
||
List<Finding> specFindings();
|
||
List<Finding> 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`.
|