Umsetzung von M1
This commit is contained in:
@@ -1,18 +1,28 @@
|
||||
---
|
||||
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 einfach gelöscht, sondern **ersetzt** durch ein sauber geschnittenes Domain-Modell. Der alte Typ wird im Rahmen von AP09 eingefroren.
|
||||
Der bestehende Typ `de.gecheckt.asv.validation.model.ValidationResult` wird nicht geändert — er wird in AP09 eingefroren.
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- AP03 (Paketstruktur)
|
||||
- AP03 (Paketstruktur vorhanden)
|
||||
- AP04 (Logging-Adapter)
|
||||
|
||||
## Scope IN
|
||||
|
||||
Folgende Typen im Paket `de.gecheckt.asv.domain.finding` (oder ähnliches Unterpaket von `domain`):
|
||||
Folgende Typen im Paket `de.gecheckt.asv.domain.finding`:
|
||||
|
||||
### `Severity` (Enum)
|
||||
- `ERROR`
|
||||
@@ -21,88 +31,108 @@ Folgende Typen im Paket `de.gecheckt.asv.domain.finding` (oder ähnliches Unterp
|
||||
|
||||
### `FindingKind` (Enum)
|
||||
- `SPEC` — Befund ist Teil des Spec-Urteils, beeinflusst `Verdict`
|
||||
- `DIAGNOSTIC` — zusätzliche Weiteranalyse, beeinflusst `Verdict` **nicht**
|
||||
- `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)
|
||||
### `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, 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
|
||||
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 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".**
|
||||
|
||||
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)
|
||||
- `VALID` — keine SPEC-ERROR-Befunde
|
||||
- `INVALID` — mindestens ein SPEC-ERROR-Befund
|
||||
- `OPERATIONAL_ERROR` — Bedienfehler (Exit-Code 2), wird in AP08 genutzt
|
||||
|
||||
### `ValidationReport` (Klasse)
|
||||
- unveränderlich
|
||||
- enthält:
|
||||
- `List<Finding> findings` (alle Befunde, SPEC und DIAGNOSTIC gemischt, Reihenfolge erhalten)
|
||||
- Methode `Verdict computeVerdict()` — berücksichtigt **nur** `kind == SPEC` und `severity == ERROR`
|
||||
- Methode `List<Finding> specFindings()` — filtert auf `kind == SPEC`
|
||||
- Methode `List<Finding> 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.
|
||||
### `ValidationReport` (unveränderliche Klasse)
|
||||
|
||||
### 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
|
||||
```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 (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)
|
||||
- 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. 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
|
||||
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 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
|
||||
- [ ] 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
|
||||
|
||||
- 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.
|
||||
- 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 `templates/ap-bericht.md`.
|
||||
`docs/arbeitspakete/m1/berichte/AP05-bericht.md` nach `docs/arbeitspakete/m1/templates/ap-bericht.md`.
|
||||
|
||||
Reference in New Issue
Block a user