# Abschlussbericht AP01 – Ist-Stand-Inventar und Delta-Analyse > **Bezug:** `docs/arbeitspakete/m1/AP01-ist-stand-inventar.md` > **Bearbeiter:** Claude Code (claude-sonnet-4-6) > **Datum:** 2026-04-09 > **Commit(s):** — (kein Commit in AP01; der Mensch committet nach Prüfung) > **Status:** ✅ abgeschlossen --- ## 1. Zusammenfassung AP01 hat den vollständigen Ist-Stand der bestehenden Code-Basis inventarisiert und ein Delta zum M1-Soll dokumentiert. Der Build ist grün (147 Tests, 0 Fehler). Die wichtigsten Befunde: Die Paketstruktur ist schichtenbasiert statt hexagonal, es existiert ein vierter Exit-Code (3), der Soll-Stand kennt nur drei (0/1/2), das Eingabe-Encoding ist hartkodiert UTF-8 statt ISO 8859-15, und mehrere M1-Kernanforderungen (Befundmodell mit Spec-/Diagnose-Trennung, Logging-Adapter, Ausgabeartefakte, Suffix-Logik) fehlen vollständig. Der bestehende Code — insbesondere Parser, Domänenmodell und Fachvalidierung — ist qualitativ gut und kann in späteren APs erhalten und migriert werden. --- ## 2. Umgesetzte Änderungen Keine Code-Änderungen. Keine `pom.xml`-Änderungen. Keine Datei-Verschiebungen. Einzige neue Datei: `docs/arbeitspakete/m1/berichte/AP01-bericht.md` (dieser Bericht). --- ## 3. Scope-Treue | Scope-Punkt aus dem Arbeitspaket | Erfüllt? | Bemerkung | |---|---|---| | Vollständige Dateiliste `src/main/java` mit Kurzbeschreibung | ✅ | 20 Klassen, alle beschrieben (Abschnitt 5.1) | | Vollständige Dateiliste `src/test/java` mit Kurzbeschreibung | ✅ | 21 Testklassen, alle beschrieben (Abschnitt 5.2) | | Dependency-Liste aus `pom.xml` | ✅ | Abschnitt 5.3 | | Grep: `org.apache.logging.log4j` | ✅ | Abschnitt 5.4 | | Grep: `StandardCharsets`, `Charset.forName` | ✅ | Abschnitt 5.5 | | Grep: `System.exit`, `EXIT_CODE` | ✅ | Abschnitt 5.6 | | Ist-Paketstruktur als Baum | ✅ | Abschnitt 5.7 | | Delta-Tabelle Paketstruktur | ✅ | Abschnitt 5.8.1 | | Delta-Tabelle Exit-Codes | ✅ | Abschnitt 5.8.2 | | Delta-Tabelle fehlende M1-Elemente | ✅ | Abschnitt 5.8.3 | | Klassifikation pro Paket | ✅ | Abschnitt 5.9 | | Keine Code-Änderungen | ✅ | keine `.java`-Datei angefasst | | Keine `pom.xml`-Änderungen | ✅ | — | | Keine Datei-Verschiebungen | ✅ | — | | Neue Dateien nur: AP01-bericht.md | ✅ | einzige neue Datei | **Wurde der Scope eingehalten?** Ja, vollständig. **Wurden Dinge außerhalb des Scopes gemacht?** Nein. --- ## 4. Abnahmekriterien | Abnahmekriterium | Erfüllt? | Nachweis | |---|---|---| | `berichte/AP01-bericht.md` existiert | ✅ | dieser Bericht | | Vollständige Dateiliste (main + test) mit Kurzbeschreibung | ✅ | Abschnitte 5.1 und 5.2 | | Dependency-Liste | ✅ | Abschnitt 5.3 | | Alle Grep-Fundstellen | ✅ | Abschnitte 5.4–5.6 | | Ist-vs-Soll-Paketstrukturbaum | ✅ | Abschnitte 5.7 und 5.8.1 | | Delta-Tabelle Exit-Codes | ✅ | Abschnitt 5.8.2 | | Delta-Tabelle fehlender M1-Elemente | ✅ | Abschnitt 5.8.3 | | Klassifikationstabelle pro Paket | ✅ | Abschnitt 5.9 | | `mvn clean verify` vor und nach AP01 identisch | ✅ | BUILD SUCCESS, 147 Tests; keine Änderungen vorgenommen | | Keine neuen Dateien außer AP01-bericht.md | ✅ | `git status` zeigt nur diese Datei | --- ## 5. Build- und Teststatus ### 5.0 Schritt 1: `mvn clean verify` - **Ergebnis:** ✅ BUILD SUCCESS - **Anzahl Tests:** 147 (0 neu; AP01 ändert keinen Code) - **Fehler / Skipped:** 0 / 0 - **Dauer:** 11,930 Sekunden - **Coverage:** noch nicht messbar (kein JaCoCo) **Warnungen beim Build (nicht blockierend):** | Warnung | Quelle | Bewertung | |---|---|---| | Annotation-Processing aktiv, obwohl kein expliziter Prozessor angegeben | javac (2×, für main und test) | kosmetisch; kann mit `-proc:none` oder `-Xlint:-options` unterdrückt werden | | Mockito self-attaching via ByteBuddy, wird in künftigen JDK-Releases nicht mehr funktionieren | Mockito / JVM | relevant für AP02: Mockito sollte als Java-Agent konfiguriert werden | | Dynamic loading of agents will be disallowed in future release | JVM (ByteBuddy-Agent) | hängt mit dem Mockito-Problem zusammen; AP02-relevant | | JVM Sharing only for boot loader classes | HotSpot | unerheblich für den Build | --- ### 5.1 Dateiliste `src/main/java` (Schritt 2) **Paket `de.gecheckt.asv.cli`** (2 Klassen) | Datei | Kurzbeschreibung | |---|---| | `AsvValidatorApplication.java` | Haupteinstiegspunkt (`main`), CLI-Bootstrap und Verdrahtung aller Komponenten per Default-Konstruktor; enthält Exit-Code-Konstanten, `System.exit`-Aufruf, Log4j2-Direktimport und liest die Eingabedatei mit `StandardCharsets.UTF_8`. | | `ValidationResultPrinter.java` | Gibt ein `ValidationResult` formatiert auf der Konsole aus (Fehler, Warnungen, Infos); enthält die Darstellungslogik, kein Logging. | **Paket `de.gecheckt.asv.domain.model`** (4 Klassen) | Datei | Kurzbeschreibung | |---|---| | `Field.java` | Java Record: ein einzelnes Feld in einem Segment mit Position (positiv), Rohwert (nicht null) und optionalem Feldnamen; unveränderlich. | | `Segment.java` | Java Record: ein Segment mit Name (nicht leer), Position (positiv) und unveränderlicher Feldliste; bietet Zugriffsmethoden (`getField`, `hasFieldAt`, `getFieldCount`). | | `Message.java` | Java Record: eine Nachricht mit Position (positiv) und unveränderlicher Segmentliste; bietet Zugriffsmethoden (`hasSegment`, `getSegments(name)`, `getFirstSegment`). | | `InputFile.java` | Java Record: eine geparste Eingabedatei mit Dateiname (nicht leer) und unveränderlicher Nachrichtenliste; bietet `getMessageCount`. | **Paket `de.gecheckt.asv.parser`** (5 Klassen) | Datei | Kurzbeschreibung | |---|---| | `InputFileParser.java` | Interface: Kontrakt für das Parsen eines Dateiinhalts (String) in ein `InputFile`-Domänenobjekt. | | `DefaultInputFileParser.java` | Standardimplementierung: liest zeilenweise via `BufferedReader`, ignoriert Leerzeilen, delegiert Tokenisierung an `SegmentLineTokenizer`; erzeugt vereinfachend **genau eine** `Message` pro Datei. | | `SegmentLineTokenizer.java` | Interface: Kontrakt für das Tokenisieren einer Segmentzeile in Segmentname und Feldliste. | | `DefaultSegmentLineTokenizer.java` | Standardimplementierung: trennt am `+`-Zeichen (hartkodiert), extrahiert Segmentname als ersten Token. | | `InputFileParseException.java` | Checked Exception für Parsing-Fehler; wraps beliebige Ursachen. | **Paket `de.gecheckt.asv.validation`** (2 Klassen) | Datei | Kurzbeschreibung | |---|---| | `InputFileValidator.java` | Interface: Kontrakt für die Gesamtvalidierung einer `InputFile`; gibt ein `ValidationResult` zurück. | | `DefaultInputFileValidator.java` | Orchestrator: führt `StructureValidator` und `FieldValidator` sequenziell aus und mergt die Teil-`ValidationResult`s zu einem Gesamt-Ergebnis. | **Paket `de.gecheckt.asv.validation.field`** (2 Klassen) | Datei | Kurzbeschreibung | |---|---| | `FieldValidator.java` | Interface: Kontrakt für die Feldvalidierung einer `InputFile`. | | `DefaultFieldValidator.java` | Implementierung: prüft Feldrohwerte auf Leerheit, Whitespace-only; prüft Feldnamen auf Leerheit; keine ASV-fachliche Logik. | **Paket `de.gecheckt.asv.validation.model`** (3 Klassen) | Datei | Kurzbeschreibung | |---|---| | `ValidationSeverity.java` | Enum mit drei Stufen: `INFO`, `WARNING`, `ERROR`. | | `ValidationError.java` | Java Record: ein einzelner Validierungsbefund mit `errorCode`, `description`, `severity`, `segmentName`, `segmentPosition`, `fieldName`, `fieldPosition`, optionalem `actualValue` und optionalem `expectedRule`. | | `ValidationResult.java` | Klasse: Sammlung von `ValidationError`-Instanzen mit Hilfsmethoden (`hasErrors`, `hasWarnings`, `hasInfos`, `getErrors`, `getWarnings`, `getInfos`, `merge`). | **Paket `de.gecheckt.asv.validation.structure`** (2 Klassen) | Datei | Kurzbeschreibung | |---|---| | `StructureValidator.java` | Interface: Kontrakt für die Strukturvalidierung einer `InputFile`. | | `DefaultStructureValidator.java` | Implementierung mit 19 Prüfregeln: strukturelle Vollständigkeit (Nachrichten, Segmente, Feldpositionen), UNH/UNT-Referenzgleichheit, Segmentanzahl-Prüfung, Nachrichtentyp (ASVREC/ASVFEH), Pflicht-Segmente und Reihenfolge in ASVREC, Rechnungskennzeichen, Rechnungsbetrag bei Storno, DGN/LEA-Prüfung, FHL für ASVFEH. | **Gesamtzahl Produktionsklassen: 20** --- ### 5.2 Dateiliste `src/test/java` (Schritt 3) | Testklasse | Tests (laut Build) | Kurzbeschreibung | |---|---|---| | `cli/AsvValidatorApplicationTest` | 3 | Testet `run()` mit fehlenden Argumenten, nicht-existenter Datei und (via Mock) korrekter Verarbeitung. | | `cli/AsvValidatorApplicationAdditionalTest` | 3 | Weitere `run()`-Szenarien: `InputFileParseException`, Validierungsfehler (Exit-Code 3), allgemeine Exception. | | `cli/ValidationResultPrinterTest` | 3 | Testet Konsolenausgabe bei Fehlern/Warnungen/Infos und leerem Ergebnis (Null-Guard). | | `domain/model/FieldTest` | 6 | Konstruktorvalidierung für `Field`: illegale Positionen, null-Rohwert, optionaler Feldname. | | `domain/model/InputFileTest` | 9 | Konstruktorvalidierung und Methoden für `InputFile`. | | `domain/model/MessageTest` | 11 | Konstruktorvalidierung und Methoden für `Message`. | | `domain/model/SegmentTest` | 12 | Konstruktorvalidierung und Methoden für `Segment`. | | `parser/DefaultInputFileParserTest` | 8 | Parsing verschiedener Dateiformate (Leerzeilen, mehrzeilig, Segmentnamen). | | `parser/DefaultSegmentLineTokenizerTest` | 3 | Tokenisierung: Segmentname-Extraktion, Feldaufteilung. | | `validation/DefaultInputFileValidatorTest` | 5 | Orchestrierung: null-Guard, Struktur- und Feldvalidator werden aufgerufen, Merge. | | `validation/field/DefaultFieldValidatorTest` | 9 | Feldvalidierungsregeln: Leerheit, Whitespace, Feldname. | | `validation/model/ValidationErrorTest` | 3 | Record-Konstruktor, Optional-Getter für `actualValue` und `expectedRule`. | | `validation/model/ValidationResultTest` | 2 | `hasErrors`, `merge`. | | `validation/structure/DefaultStructureValidatorTest` | 22 | Allgemeine Strukturregeln (Regeln 1–11 aus `DefaultStructureValidator`). | | `validation/structure/DefaultStructureValidatorTestAdditional` | 0 | Datei vorhanden, keine `@Test`-Methoden; vermutlich Hilfsmethoden oder Vorbereitung. | | `validation/structure/DefaultStructureValidatorAsvfehFhlSegmentTest` | 8 | FHL-Segment-Pflicht für ASVFEH (Regel 19). | | `validation/structure/DefaultStructureValidatorAsvrecRechnungsbetragTest` | 7 | Rechnungsbetrag `0,00` bei Storno-Rechnungskennzeichen (Regel 17). | | `validation/structure/DefaultStructureValidatorAsvrecRechnungskennzeichenTest` | 12 | Rechnungskennzeichen-Prüfungen (Regeln 15–16). | | `validation/structure/DefaultStructureValidatorAsvrecSegmentCardinalityTest` | 9 | Segment-Kardinalität IFA/REA/IVA (Regel 18). | | `validation/structure/DefaultStructureValidatorAsvrecSegmentOrderTest` | 5 | Segment-Reihenfolge IFA → REA → IVA (Regel 14). | | `validation/structure/DefaultStructureValidatorAsvrecSegmentsTest` | 7 | Pflicht-Segmente IFA, REA, IVA (Regel 13). | | **Gesamt** | **147** | | **Gesamtzahl Testklassen: 21** (davon 1 ohne `@Test`-Methoden) --- ### 5.3 Dependencies aus `pom.xml` (Schritt 3 Ergänzung) | Dependency | Version | Scope | Zweck | |---|---|---|---| | `org.apache.logging.log4j:log4j-api` | 2.20.0 | compile | Log4j2 API | | `org.apache.logging.log4j:log4j-core` | 2.20.0 | compile | Log4j2 Implementierung | | `org.junit.jupiter:junit-jupiter` | 5.9.2 | test | JUnit 5 | | `org.mockito:mockito-core` | 5.23.0 | test | Mockito | **Plugins:** | Plugin | Version | Zweck | |---|---|---| | `maven-compiler-plugin` | 3.11.0 | Compiler-Konfiguration (Java 21) | | `maven-surefire-plugin` | 3.0.0 | Test-Runner | **Fehlend laut M1-Soll:** `slf4j-api`, `log4j-slf4j2-impl`, `maven-jar-plugin` (Main-Class), `jacoco-maven-plugin`, PIT/Pitest-Plugin. --- ### 5.4 Grep: Log4j2-Direktimporte (Schritt 4) ``` src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:23: import org.apache.logging.log4j.LogManager; src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:24: import org.apache.logging.log4j.Logger; ``` **Befund:** Log4j2-Typen werden ausschließlich in `AsvValidatorApplication` direkt importiert. Kein Test-Code importiert Log4j2. Laut Soll-Architektur dürfen Log4j2-Typen nur in `bootstrap` und `adapter.out.logging` sichtbar sein. --- ### 5.5 Grep: Zeichensatz-Setzen (Schritt 5) ``` src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:18: import java.nio.charset.StandardCharsets; src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:151: String fileContent = Files.readString(path, StandardCharsets.UTF_8); ``` **Befund:** Die Eingabedatei wird mit `StandardCharsets.UTF_8` gelesen. Laut Soll-Architektur (`technik-und-architektur.md`) und fachlicher Anforderung (`R-GLOBAL-ZEICHENSATZ-001`) ist **ISO 8859-15** verpflichtend. `Charset.forName` wird nicht verwendet. Kein weiterer Zeichensatz-Code im gesamten Projekt. --- ### 5.6 Grep: `System.exit` und Exit-Code-Konstanten (Schritt 6) ``` src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:35: private static final int EXIT_CODE_SUCCESS = 0; src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:36: private static final int EXIT_CODE_INVALID_ARGUMENTS = 1; src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:37: private static final int EXIT_CODE_FILE_ERROR = 2; src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:38: private static final int EXIT_CODE_VALIDATION_ERRORS = 3; src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:83: System.exit(exitCode); src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:96: return EXIT_CODE_INVALID_ARGUMENTS; src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:112: return result.hasErrors() ? EXIT_CODE_VALIDATION_ERRORS : EXIT_CODE_SUCCESS; src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:117: return EXIT_CODE_FILE_ERROR; src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:121: return EXIT_CODE_FILE_ERROR; src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java:125: return EXIT_CODE_FILE_ERROR; ``` **Befund:** `System.exit` wird genau einmal aufgerufen (Zeile 83, in `main`). Die Methode `run()` gibt einen `int`-Exit-Code zurück und ist damit testbar — das ist ein positives Muster. Es existieren vier Exit-Code-Konstanten statt drei. --- ### 5.7 Ist-Paketstruktur (Schritt 7) ``` src/main/java/de/gecheckt/asv/ ├── cli/ │ ├── AsvValidatorApplication.java │ └── ValidationResultPrinter.java ├── domain/ │ └── model/ │ ├── Field.java │ ├── InputFile.java │ ├── Message.java │ └── Segment.java ├── parser/ │ ├── DefaultInputFileParser.java │ ├── DefaultSegmentLineTokenizer.java │ ├── InputFileParseException.java │ ├── InputFileParser.java │ └── SegmentLineTokenizer.java └── validation/ ├── DefaultInputFileValidator.java ├── InputFileValidator.java ├── field/ │ ├── DefaultFieldValidator.java │ └── FieldValidator.java ├── model/ │ ├── ValidationError.java │ ├── ValidationResult.java │ └── ValidationSeverity.java └── structure/ ├── DefaultStructureValidator.java └── StructureValidator.java src/test/java/de/gecheckt/asv/ ├── cli/ │ ├── AsvValidatorApplicationAdditionalTest.java │ ├── AsvValidatorApplicationTest.java │ └── ValidationResultPrinterTest.java ├── domain/ │ └── model/ │ ├── FieldTest.java │ ├── InputFileTest.java │ ├── MessageTest.java │ └── SegmentTest.java ├── parser/ │ ├── DefaultInputFileParserTest.java │ └── DefaultSegmentLineTokenizerTest.java └── validation/ ├── DefaultInputFileValidatorTest.java ├── field/ │ └── DefaultFieldValidatorTest.java ├── model/ │ ├── ValidationErrorTest.java │ └── ValidationResultTest.java └── structure/ ├── DefaultStructureValidatorAsvfehFhlSegmentTest.java ├── DefaultStructureValidatorAsvrecRechnungsbetragTest.java ├── DefaultStructureValidatorAsvrecRechnungskennzeichenTest.java ├── DefaultStructureValidatorAsvrecSegmentCardinalityTest.java ├── DefaultStructureValidatorAsvrecSegmentOrderTest.java ├── DefaultStructureValidatorAsvrecSegmentsTest.java ├── DefaultStructureValidatorTest.java └── DefaultStructureValidatorTestAdditional.java ``` **Soll-Paketstruktur** laut `technik-und-architektur.md`: ``` de.gecheckt.asv. ├── domain ├── application ├── adapter.in.cli ├── adapter.out.filesystem ├── adapter.out.parsing ├── adapter.out.crypto ├── adapter.out.reporting ├── adapter.out.logging └── bootstrap ``` --- ### 5.8 Delta-Tabellen (Schritt 8) #### 5.8.1 Paketstruktur Ist vs. Soll | Soll-Paket | Entsprechung im Ist | Status | Bemerkung | |---|---|---|---| | `domain` | `domain.model` | ⚠️ teilweise | Nur Dateimodell vorhanden; Befundmodell fehlt; Paketname ist `domain.model`, nicht `domain` | | `application` | — | ❌ fehlt | Orchestrierungslogik liegt in `validation` (DefaultInputFileValidator) | | `adapter.in.cli` | `cli` | ⚠️ teilweise | CLI-Code vorhanden, aber falscher Paketname; enthält auch Bootstrap-Logik | | `adapter.out.filesystem` | — | ❌ fehlt | Dateisystemzugriff (`Files.readString`) liegt direkt in `AsvValidatorApplication` | | `adapter.out.parsing` | `parser` | ⚠️ teilweise | Parser vorhanden und gut, aber falscher Paketname | | `adapter.out.crypto` | — | ❌ fehlt | In M1 noch nicht benötigt (PKCS#7 erst in M8) | | `adapter.out.reporting` | `cli` (ValidationResultPrinter) | ⚠️ teilweise | Klasse existiert, liegt im falschen Paket | | `adapter.out.logging` | — | ❌ fehlt | Log4j2 direkt in `cli.AsvValidatorApplication` | | `bootstrap` | — | ❌ fehlt | Bootstrap-Logik in `AsvValidatorApplication.main()` und Default-Konstruktor | | — | `validation` | ⚠️ kein Soll-Äquivalent | Application-Logik im falschen Paket | | — | `validation.model` | ⚠️ kein Soll-Äquivalent | Gehört fachlich näher zu `domain` | | — | `validation.structure` | ⚠️ kein Soll-Äquivalent | Teils `domain`-Logik, teils `application`-Logik | | — | `validation.field` | ⚠️ kein Soll-Äquivalent | Teils `domain`-Logik, teils `application`-Logik | #### 5.8.2 Exit-Codes Ist vs. Soll | Konstante (Ist) | Ist-Wert | Soll-Wert | Soll-Semantik | Bewertung | |---|---|---|---|---| | `EXIT_CODE_SUCCESS` | `0` | `0` | gültig | ✅ übereinstimmend | | `EXIT_CODE_INVALID_ARGUMENTS` | `1` | `2` | Bedienfehler | ❌ Diskrepanz: Ist=1, Soll=2 | | `EXIT_CODE_FILE_ERROR` | `2` | `2` | Bedienfehler | ⚠️ zufällig gleicher Wert, aber semantisch überlappt mit `EXIT_CODE_INVALID_ARGUMENTS`; laut Soll ist `2` der einzige Bedienfehler-Code | | `EXIT_CODE_VALIDATION_ERRORS` | `3` | `1` | ungültig | ❌ Diskrepanz: Ist=3, Soll=1; dieser Code existiert im Soll nicht | **Kernproblem:** Der Ist-Stand hat **vier** Exit-Codes; der Soll-Stand hat **drei**. `EXIT_CODE_INVALID_ARGUMENTS=1` und `EXIT_CODE_VALIDATION_ERRORS=3` sind gegenüber dem Soll vertauscht/falsch. `EXIT_CODE_INVALID_ARGUMENTS` und `EXIT_CODE_FILE_ERROR` sollen im Soll zusammengeführt werden zu einem einzigen Bedienfehler-Code `2`. #### 5.8.3 Fehlende M1-Elemente | M1-Element | Status | Ist-Befund | Soll-Anforderung | |---|---|---|---| | Befundmodell mit Spec-/Diagnose-Trennung | ❌ fehlt | `ValidationError`/`ValidationResult` kennen keine Trennung zwischen Spec-Urteil und diagnostischer Weiteranalyse; alles in einem `List` | Strukturell trennen: verbindliches Prüfurteil (Spec) ≠ diagnostische Weiteranalyse; Diagnose darf Spec-Urteil nicht verändern (AP05) | | SLF4J als Logging-Fassade | ❌ fehlt | Log4j2 direkt importiert in `AsvValidatorApplication`; kein SLF4J in `pom.xml` | SLF4J als Fassade, Log4j2 als Bindung; Bindung nur in `adapter.out.logging` und `bootstrap` (AP04) | | Berichtdatei im Eingabeverzeichnis (`.txt`) | ❌ fehlt | Kein File-Output implementiert; nur Konsolenausgabe via `ValidationResultPrinter` | `.txt`-Datei im Verzeichnis der Eingabedatei, UTF-8 (AP07) | | Log-Datei im Eingabeverzeichnis (`.log`) | ❌ fehlt | Kein File-Logging konfiguriert | `.log`-Datei im Verzeichnis der Eingabedatei, UTF-8 (AP07) | | Suffix-Logik `_v1`/`_v2` | ❌ fehlt | Kein Mehrfachlauf-Mechanismus vorhanden | Laufendes Suffix bei bereits existierenden Ausgabedateien (AP07) | | Minimalbericht bei Exit-Code 2 | ❌ fehlt | Bei Fehlern nur `System.err.println`, kein strukturierter Bericht; kein Bericht bei Bedienfehler | Auch bei Exit-Code 2 muss ein nachvollziehbarer Minimalbericht entstehen (AP08) | | ISO 8859-15 als Eingabe-Encoding | ❌ fehlt | `Files.readString(path, StandardCharsets.UTF_8)` — hartkodiert UTF-8 | `StandardCharsets.ISO_8859_1` reicht nicht; muss `ISO-8859-15` (Level C) sein; Level-C-Charset nicht in Standard-Java-API (AP02/AP03) | | Hexagonale Paketstruktur | ❌ fehlt | Schichtenbasierte Struktur: `cli`, `domain`, `parser`, `validation` | Hexagonale Trennung: `domain`, `application`, `adapter.*`, `bootstrap` (AP03) | | Manueller Bootstrap per Constructor Injection | ⚠️ teilweise | Default-Konstruktor in `AsvValidatorApplication` verdrahtet Komponenten per `new`; aber im falschen Paket und vermischt mit CLI-Logik | Separates `bootstrap`-Paket mit dünner Bootstrap-Klasse; vollständig entkoppelt (AP06) | | JaCoCo im Build | ❌ fehlt | Kein `jacoco-maven-plugin` in `pom.xml` | Coverage-Messung als Quality-Gate (AP02) | | PIT / Mutation-Testing im Build | ❌ fehlt | Kein `pitest-maven`-Plugin in `pom.xml` | Mutation-Testing-Profil (AP02) | --- ### 5.9 Klassifikation pro Ist-Paket (Schritt 9) | Ist-Paket | enthält | Klassifikation | Begründung | |---|---|---|---| | `cli` | `AsvValidatorApplication`, `ValidationResultPrinter` | **behalten und anpassen** | `AsvValidatorApplication` enthält Bootstrap-Logik, CLI-Logik, Dateisystemzugriff und Logging vermischt; muss in AP03/AP06 aufgeteilt werden. `ValidationResultPrinter` ist strukturell sauber und kann nach `adapter.out.reporting` migriert werden. | | `domain.model` | `Field`, `Segment`, `Message`, `InputFile` | **behalten und migrieren** | Records sind technisch gut und korrekt; das Domänenmodell der Dateistruktur wird erhalten. Paket muss zu `domain` (ohne Sub-Paket `model`) migriert oder dort integriert werden. Das Befundmodell fehlt vollständig und wird in AP05 neu gebaut. | | `parser` | `InputFileParser`, `DefaultInputFileParser`, `SegmentLineTokenizer`, `DefaultSegmentLineTokenizer`, `InputFileParseException` | **behalten und migrieren** | Gut strukturierter, wertvoller Parser-Code mit sauberem Interface-Kontrakt; muss nach `adapter.out.parsing` migriert werden. Der hartkodierte `+`-Trenner ist ein Rest-Risiko (UNA-Segment fehlt). | | `validation` | `InputFileValidator`, `DefaultInputFileValidator` | **behalten und anpassen** | Orchestrator-Pattern ist gut (Interface + Implementierung, Constructor Injection, Merge-Logik); muss nach `application` migriert und ggf. an das neue Befundmodell angepasst werden. | | `validation.model` | `ValidationSeverity`, `ValidationError`, `ValidationResult` | **behalten und anpassen** | Strukturell solide; `ValidationError` als Record ist gut. Das Befundmodell kennt keine Spec-/Diagnose-Trennung und wird in AP05 erweitert. Paketziel: Aufgehen in `domain` (Befundmodell) oder umbenannt als `domain.finding`. | | `validation.structure` | `StructureValidator`, `DefaultStructureValidator` | **später verwenden (M3+)** | Enthält substantielle ASVREC/ASVFEH-Fachvalidierung mit 19 Regeln — wertvoll, aber M1-fremd. In AP09 einfrieren (als Vorbau für M3+ erhalten, nicht aktiv in den M1-Lauf verdrahtet). | | `validation.field` | `FieldValidator`, `DefaultFieldValidator` | **später verwenden (M3+)** | Ähnlich wie `validation.structure`: wertvolle Feldlogik, die in M1 nicht weiterentwickelt wird; in AP09 einfrieren. | --- ## 6. Rest-Risiken und offene Punkte 1. **Trennzeichen hartkodiert (`+`):** `DefaultSegmentLineTokenizer` trennt immer am `+`-Zeichen, ohne das UNA-Segment auszuwerten. ASV erlaubt (gemäß Spezifikation) ein optionales UNA-Segment, das die tatsächlich verwendeten Trennzeichen definiert. Dies ist ein bekanntes technisches Risiko für den Parser (relevant ab M3). 2. **Mockito-Agent-Warnung:** Mockito 5.23.0 nutzt ByteBuddy-Self-Attach, das in künftigen JDK-Versionen nicht mehr erlaubt sein wird. In AP02 sollte Mockito als expliziter Java-Agent konfiguriert werden (`argLine` in `maven-surefire-plugin`). 3. **ISO 8859-15 nicht in Standard-Java-API:** `java.nio.charset.StandardCharsets` kennt nur `ISO_8859_1` (Latin-1), nicht ISO 8859-15 (Latin-9). Für ISO 8859-15 muss `Charset.forName("ISO-8859-15")` verwendet werden. Dies muss in AP02 oder AP03 sorgfältig behandelt werden (Charset-Verfügbarkeit im JDK prüfen). 4. **`DefaultStructureValidatorTestAdditional` ohne Tests:** Die Datei existiert, enthält aber keine `@Test`-Methoden. Dies ist unkritisch, sollte aber in AP10 aufgeräumt werden (entweder Tests hinzufügen oder Datei entfernen). 5. **`DefaultInputFileParser` erzeugt immer genau eine Message:** Der Parser erzeugt per Design „vereinfachend" genau eine Nachricht pro Datei (`// For this simplified version, we assume exactly one message per file`). Dies ist für M1 akzeptabel, muss aber spätestens in M3 überarbeitet werden. 6. **Klassifikation als Arbeitsgrundlage:** Die Einschätzungen in Abschnitt 5.9 sind konservativ; die tatsächliche Entscheidung über Verbleib oder Neubau kann in späteren APs revidiert werden. 7. **Keine Main-Class im JAR-Manifest:** Das aktuelle `pom.xml` konfiguriert kein `maven-jar-plugin` mit `Main-Class`-Manifest-Eintrag. Das JAR ist nach `mvn package` nicht direkt mit `java -jar` startbar. --- ## 7. Empfehlungen für Folge-Arbeitspakete - **AP02 (Build-Infrastruktur):** SLF4J- und Log4j2-SLF4J-Bridge-Dependency hinzufügen, JaCoCo und PIT konfigurieren, `maven-jar-plugin` mit `Main-Class` einrichten, Mockito als Java-Agent in `maven-surefire-plugin` konfigurieren (Warnung beheben). - **AP03 (Paketstruktur):** Die Klassifikationstabelle (Abschnitt 5.9) kann direkt als Migrationsleitfaden verwendet werden. `validation.structure` und `validation.field` sind bewusst für `später verwenden (M3+)` markiert — AP09 soll sie einfrieren. - **AP05 (Befundmodell):** Das bestehende `ValidationError`/`ValidationResult`-Modell kann als Ausgangspunkt dienen, muss aber um die Spec-/Diagnose-Trennung erweitert werden. `ValidationSeverity` könnte erhalten bleiben. - **AP06 (Bootstrap/CLI):** Exit-Code-Konstanten komplett ersetzen: `0` = gültig, `1` = ungültig, `2` = Bedienfehler. Den hartkodiert-UTF-8-Lesezugriff auf ISO 8859-15 umstellen. --- ## 8. Reviewer-Checkliste - [x] Alle im Arbeitspaket genannten Scope-IN-Punkte sind nachweislich umgesetzt (Abschnitte 5.1–5.9) - [x] Keine Scope-OUT-Punkte wurden angefasst (keine Code-, `pom.xml`- oder Datei-Änderungen) - [x] Abnahmekriterien sind mit konkreten Nachweisen belegt (Abschnitt 4) - [x] `mvn clean verify` ist grün (147 Tests, BUILD SUCCESS — Abschnitt 5.0) - [ ] Der Commit für dieses AP hat eine sprechende Message (`M1-AP01: Ist-Stand-Inventar und Delta-Analyse`) — _Commit liegt beim Menschen_ - [x] Keine Regeln der Grunddokumente (Spec, Fachliche, Technik) wurden verletzt - [x] Rest-Risiken sind ehrlich dokumentiert (Abschnitt 6)