Dokumentation und Arbeitspakete angelegt

This commit is contained in:
2026-04-09 06:27:29 +02:00
parent fa36297e32
commit 79109594aa
13 changed files with 1069 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
# AP01 Ist-Stand-Inventar und Delta-Analyse
## Ziel
Den **tatsächlichen Ist-Zustand** der bestehenden Code-Basis vollständig erfassen und ein **Delta** zum M1-Soll dokumentieren, bevor irgendetwas umgebaut wird. Ohne dieses AP besteht das Risiko, dass spätere APs an der Realität vorbeiplanen.
## Voraussetzungen
- keine (erstes AP)
## Scope IN
- vollständige Dateiliste unter `src/main/java/` und `src/test/java/` mit Kurzbeschreibung jeder Klasse (ein Satz pro Klasse)
- Auflistung aller externen Dependencies aus `pom.xml` inkl. Versionen
- Identifikation aller Stellen, an denen Log4j2-Typen (`org.apache.logging.log4j.*`) direkt importiert werden
- Identifikation aller Stellen, an denen Zeichensätze explizit gesetzt werden (Grep nach `StandardCharsets`, `Charset.forName`)
- Identifikation aller `System.exit`- und Exit-Code-Konstanten
- Delta-Tabelle: Ist-Paketstruktur vs. Soll-Paketstruktur aus `technik-und-architektur.md`
- Delta-Tabelle: Ist-Exit-Codes vs. Soll-Exit-Codes (`0/1/2`)
- Delta-Tabelle: vorhandene vs. fehlende Elemente für M1 (Befundmodell mit Spec-/Diagnose-Trennung, SLF4J-Fassade, Berichtdatei, Log-Datei, Suffix-Logik, Minimalbericht, ISO 8859-15 als Eingabe-Encoding)
- Klassifikation jedes vorhandenen Pakets: **behalten und migrieren**, **behalten und anpassen**, **neu bauen**, **später verwenden (M3+)**
## Scope OUT
- keinerlei Code-Änderungen
- keinerlei `pom.xml`-Änderungen
- keinerlei Datei-Verschiebungen
- keine neuen Dateien außer dem Bericht selbst
## Schritte
1. Repo lokal auschecken, `mvn clean verify` laufen lassen, Ergebnis festhalten (grün/rot, Anzahl Tests, Warnungen)
2. `find src/main/java -name "*.java" | sort` und jede Datei mit ein bis zwei Sätzen kurz beschreiben
3. `find src/test/java -name "*.java" | sort` analog
4. `grep -rn "org.apache.logging.log4j" src/` — alle Fundstellen auflisten
5. `grep -rn "StandardCharsets\|Charset.forName" src/` — alle Fundstellen auflisten
6. `grep -rn "System.exit\|EXIT_CODE" src/` — alle Fundstellen auflisten
7. aktuelle Paketstruktur als Baum zeichnen
8. Delta-Tabellen gemäß Scope IN erstellen
9. Klassifikation pro Paket vornehmen
10. Abschlussbericht nach `templates/ap-bericht.md` schreiben
## Abnahmekriterien
- Abschlussbericht `berichte/AP01-bericht.md` existiert und enthält:
- vollständige Dateiliste (main + test) mit Kurzbeschreibung
- Dependency-Liste
- alle Grep-Fundstellen
- Ist-vs-Soll-Paketstrukturbaum
- Delta-Tabelle Exit-Codes
- Delta-Tabelle fehlender M1-Elemente
- Klassifikationstabelle pro Paket
- `mvn clean verify` ist vor und nach diesem AP identisch (es wurde nichts geändert)
- keine neuen Dateien im Repo außer dem Abschlussbericht
## Rest-Risiken und offene Punkte
- Die Klassifikation „behalten" vs. „neu bauen" ist eine Einschätzung und kann in späteren APs revidiert werden müssen. Das ist okay, solange es dokumentiert wird.
## Bericht
`docs/arbeitspakete/m1/berichte/AP01-bericht.md` nach `templates/ap-bericht.md`.

View File

@@ -0,0 +1,70 @@
# AP02 Build-Infrastruktur härten
## Ziel
Die `pom.xml` so erweitern, dass alle für M1 und die späteren Quality-Gates in M9 benötigten Bausteine bereitstehen, ohne schon Funktionalität zu implementieren. Dazu gehören **SLF4J als Fassade** (verlangt von `technik-und-architektur.md`), **JaCoCo** und **PIT** für die differenzierten Qualitätsgates, sowie das **maven-jar-plugin** für ein ausführbares JAR.
## Voraussetzungen
- AP01 abgeschlossen
## Scope IN
- `pom.xml` ergänzen um:
- **SLF4J API** (`org.slf4j:slf4j-api`) als Compile-Dependency
- **log4j-slf4j2-impl** (`org.apache.logging.log4j:log4j-slf4j2-impl`) als Runtime-Bindung (SLF4J → Log4j2)
- **maven-jar-plugin** mit `Main-Class` = Bootstrap-Klasse (Name ist zu diesem Zeitpunkt noch offen, Platzhalter eintragen, in AP06 final setzen)
- **jacoco-maven-plugin** für Coverage, an `verify` gebunden, **ohne** harte Schwellwerte in M1 (die kommen erst in M9)
- **pitest-maven** als optionales Ziel (`mvn -P mutation test`), ebenfalls **ohne** harte Schwelle in M1
- **maven-surefire-plugin** bleibt wie bisher, ggf. Version aktualisieren falls nötig
- `.editorconfig` im Repo-Root anlegen mit:
- UTF-8 als Default-Encoding für Quellcode
- LF als Zeilenende
- 4 Spaces Einrückung für Java
- `trim_trailing_whitespace = true`
- `insert_final_newline = true`
- `.gitattributes` anlegen:
- `* text=auto eol=lf`
- `*.bat text eol=crlf`
- `*.java text eol=lf`
- `*.md text eol=lf`
## Scope OUT
- Umstellung bestehender Klassen von Log4j2-API auf SLF4J (kommt in AP04)
- Einführung von Coverage-Schwellwerten (kommt erst in M9)
- Einführung von PIT-Schwellwerten (kommt erst in M9)
- Änderungen an Quellcode
- Änderungen an Tests
## Schritte
1. Branch `m1/ap02-build-infra` anlegen
2. SLF4J-Dependencies in `pom.xml` eintragen; **keine** Imports in Quellcode ändern
3. JaCoCo-Plugin eintragen, an `verify` binden
4. PIT-Plugin in Profil `mutation` eintragen
5. maven-jar-plugin eintragen mit Platzhalter `Main-Class` (Wert: `de.gecheckt.asv.bootstrap.Main` — wird in AP06 Realität)
6. `.editorconfig` und `.gitattributes` anlegen
7. `mvn clean verify` laufen lassen, muss grün sein
8. `mvn -P mutation test` laufen lassen, muss grün sein (PIT muss die bestehenden Tests durchkauen können, auch wenn noch kaum was da ist)
9. Commit `M1-AP02: Build-Infrastruktur härten (SLF4J, JaCoCo, PIT, JAR-Plugin)`
10. Abschlussbericht schreiben
## Abnahmekriterien
- `pom.xml` enthält: `slf4j-api`, `log4j-slf4j2-impl`, `maven-jar-plugin`, `jacoco-maven-plugin`, `pitest-maven`
- `mvn clean verify` ist grün
- `mvn -P mutation test` läuft ohne Fehler durch (Score ist **irrelevant** in M1)
- JaCoCo erzeugt einen Report unter `target/site/jacoco/`
- `.editorconfig` und `.gitattributes` liegen im Repo-Root
- keine Änderungen an `.java`-Dateien
- Abschlussbericht `berichte/AP02-bericht.md` liegt vor
## Rest-Risiken und offene Punkte
- Der `Main-Class`-Eintrag im JAR-Plugin zeigt bis AP06 auf eine Klasse, die noch nicht existiert. Das ist okay, solange das JAR-Plugin die Datei nicht beim Packen validiert. Alternativ bis AP06 auf die bestehende `AsvValidatorApplication` zeigen lassen und in AP06 umbiegen.
- PIT ohne Schwelle ist nur eine Trockenübung für M1. Die echten Schwellen werden in M9 aktiviert.
## Bericht
`docs/arbeitspakete/m1/berichte/AP02-bericht.md` nach `templates/ap-bericht.md`.

View File

@@ -0,0 +1,72 @@
# AP03 Hexagonale Paketstruktur anlegen und Ist-Code migrieren
## Ziel
Die **Soll-Paketstruktur** aus `technik-und-architektur.md` im Projekt anlegen und den **bestehenden Code evolutionär** in die neuen Pakete verschieben, ohne Funktionalität zu verlieren. Alle bestehenden Tests müssen weiterhin grün laufen.
## Voraussetzungen
- AP01 (Ist-Stand bekannt)
- AP02 (Build ist grün)
## Scope IN
- Anlage der Soll-Pakete:
```
de.gecheckt.asv.domain
de.gecheckt.asv.application
de.gecheckt.asv.adapter.in.cli
de.gecheckt.asv.adapter.out.filesystem
de.gecheckt.asv.adapter.out.parsing
de.gecheckt.asv.adapter.out.reporting
de.gecheckt.asv.adapter.out.logging
de.gecheckt.asv.bootstrap
```
(Paket `adapter.out.crypto` kommt erst in M8.)
- Migration des bestehenden Codes nach folgender Zuordnung:
- `de.gecheckt.asv.cli.AsvValidatorApplication` → **vorerst** nach `adapter.in.cli`, wird in AP06 refaktoriert
- `de.gecheckt.asv.cli.ValidationResultPrinter` → `adapter.out.reporting` (technische Berichtsausgabe ist Adapter-Zuständigkeit)
- `de.gecheckt.asv.domain.model.*` → `domain` (Paket `.model` darf bleiben als Unterpaket von `domain`)
- `de.gecheckt.asv.parser.*` → `adapter.out.parsing`
- `de.gecheckt.asv.validation.*` (inkl. `field/`, `structure/`, `model/`) → vorerst unter `application` belassen, bis AP09 klärt, was davon wirklich nach `application` gehört und was ggf. in einem eigenen Unterpaket „eingefroren" bleibt
- alle `package`-Deklarationen und `import`-Statements anpassen
- alle Tests entsprechend mit verschieben
- Build und Tests bleiben grün
- einfaches Package-Diagramm als Markdown-Tabelle im Abschlussbericht
## Scope OUT
- inhaltliche Umstellung der Klassen (Exit-Codes, Zeichensatz, Befundmodell — das kommt in späteren APs)
- Einführung neuer Klassen
- Löschen von Klassen
- Refactoring von Methoden
## Schritte
1. Branch `m1/ap03-hexagonale-pakete`
2. Leerverzeichnisse für die Soll-Pakete anlegen (notfalls `.gitkeep`, wird später entfernt)
3. Klassen paketweise verschieben (IDE-Refactoring „Move Class" hilft hier enorm)
4. Nach jeder Paket-Migration: `mvn clean compile` laufen lassen, muss grün bleiben
5. Nach allen Migrationen: `mvn clean verify` — muss grün sein
6. Kurze Paket-Beschreibung pro Paket in einem `package-info.java` hinzufügen (deutsche JavaDoc, ein bis zwei Sätze)
7. Commit `M1-AP03: Hexagonale Paketstruktur angelegt, Ist-Code migriert`
8. Abschlussbericht schreiben
## Abnahmekriterien
- alle oben genannten Soll-Pakete existieren als Java-Packages
- kein Code ist verloren gegangen: `git log --stat` zeigt nur Verschiebungen und Import-Anpassungen, keine Löschungen
- `mvn clean verify` ist grün
- jede neue Paket-Wurzel hat ein `package-info.java` mit deutscher Kurzbeschreibung
- Abschlussbericht enthält eine **Vorher-Nachher-Tabelle** jeder migrierten Klasse
- keine neuen Features
## Rest-Risiken und offene Punkte
- Die Zuordnung der Validation-Klassen nach `application` ist **provisorisch**. AP09 entscheidet endgültig, was davon in M1 aktiv bleibt und was eingefroren wird.
- `AsvValidatorApplication` bleibt vorerst im CLI-Adapter, wird aber in AP06 zerlegt (Bootstrap + dünner CLI-Adapter).
- Die Tests-Struktur sollte die neue Paketstruktur spiegeln; falls das mit IDE-Move automatisch passiert: gut. Falls nicht: manuell nachziehen.
## Bericht
`docs/arbeitspakete/m1/berichte/AP03-bericht.md` nach `templates/ap-bericht.md`.

View File

@@ -0,0 +1,62 @@
# AP04 Logging-Adapter (SLF4J-Fassade + Log4j2-Bindung)
## Ziel
Sicherstellen, dass im gesamten Quellcode **nur noch SLF4J-Typen importiert werden** (`org.slf4j.Logger`, `org.slf4j.LoggerFactory`), außer in einem dedizierten **Logging-Adapter** und im **Bootstrap**. Die konkrete Log4j2-Bindung darf nur an diesen zwei Stellen sichtbar sein, wie von `technik-und-architektur.md` gefordert.
## Voraussetzungen
- AP03 (Paketstruktur vorhanden)
## Scope IN
- Alle Stellen im Produktivcode, die `org.apache.logging.log4j.LogManager` oder `org.apache.logging.log4j.Logger` importieren, werden umgestellt auf:
```java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
```
- Anlage einer minimalen `log4j2.xml` in `src/main/resources/`:
- Console-Appender (StdErr)
- File-Appender mit Zielpfad, der später (AP07) durch den Bootstrap überschrieben wird; für M1 genügt ein Default-Pfad `logs/asv-format-validator.log`
- Log-Level `INFO` für `de.gecheckt.asv`, `WARN` für alles andere
- Deutsche Log-Texte bleiben auf Deutsch
- Anlage eines `LoggingConfigurator` oder ähnlich im Paket `adapter.out.logging`, der Log4j2 **programmatisch** konfigurieren kann (Zielpfad der Log-Datei setzbar). Für M1 reicht eine Klasse mit einer Methode `void configureLogFile(Path logFile)`, die noch keine tiefe Magie macht, aber das Interface definiert.
- Architekturcheck: per `grep` sicherstellen, dass außerhalb von `adapter.out.logging` und `bootstrap` keine `org.apache.logging.log4j.*`-Imports mehr existieren.
## Scope OUT
- tatsächliche dynamische Log-Datei-Umleitung pro Lauf (das ist AP07)
- Log-Rotation, Log-Compression, eigene Appender-Klassen
- Logging-Policies, Log-Level pro Klasse
- Umbau der Log-Nachrichten selbst (Wortlaut, Formatierung)
## Schritte
1. Branch `m1/ap04-logging-adapter`
2. In allen Produktiv-Klassen außer `adapter.out.logging` und `bootstrap`: Log4j2-Imports durch SLF4J-Imports ersetzen
3. Minimale `log4j2.xml` in `src/main/resources/` anlegen
4. `LoggingConfigurator` in `adapter.out.logging` anlegen (Skelett)
5. `mvn clean verify` laufen lassen, muss grün sein
6. `grep -rn "org.apache.logging.log4j" src/main/java/ | grep -v "adapter/out/logging\|bootstrap"` muss **leer** sein
7. Commit `M1-AP04: Logging-Adapter, SLF4J-Fassade etabliert`
8. Abschlussbericht schreiben
## Abnahmekriterien
- kein Import von `org.apache.logging.log4j.*` außerhalb von `adapter.out.logging` und `bootstrap` (Grep-Nachweis im Bericht)
- `log4j2.xml` in `src/main/resources/` vorhanden
- `LoggingConfigurator`-Klasse in `adapter.out.logging` vorhanden (mindestens Skelett)
- `mvn clean verify` ist grün
- alle bestehenden Tests laufen weiterhin (SLF4J ist API-kompatibel; falls Tests wegen Logger-Mocks brechen, müssen sie angepasst werden — dann im Bericht dokumentieren)
- Abschlussbericht liegt vor
## Rest-Risiken und offene Punkte
- Falls bestehende Tests Log4j2-Logger mocken: Anpassung nötig. Im Zweifel Logger-Mocks entfernen, Logging ist keine Testlogik.
- `log4j2.xml` hat in M1 einen statischen Dateipfad. Der dynamische Pfad pro Lauf kommt erst in AP07.
## Bericht
`docs/arbeitspakete/m1/berichte/AP04-bericht.md` nach `templates/ap-bericht.md`.

View File

@@ -0,0 +1,108 @@
# 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<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.
### 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`.

View File

@@ -0,0 +1,96 @@
# AP06 Bootstrap und CLI-Adapter
## Ziel
Die bestehende `AsvValidatorApplication` wird in zwei klar getrennte Verantwortlichkeiten zerlegt:
1. **Bootstrap** (`de.gecheckt.asv.bootstrap.Main`) — verdrahtet die Komponenten manuell per Constructor Injection und ist der einzige `public static void main`.
2. **CLI-Adapter** (`de.gecheckt.asv.adapter.in.cli.CliRunner` oder ähnlich) — nimmt CLI-Argumente entgegen, ruft die Application-Schicht auf, übersetzt das Ergebnis in einen Exit-Code.
Zusätzlich werden die **Exit-Codes spec-konform** auf `0/1/2` umgestellt.
## Voraussetzungen
- AP03, AP04, AP05
## Scope IN
### Bootstrap
- Klasse `de.gecheckt.asv.bootstrap.Main` mit `public static void main(String[] args)`
- verdrahtet manuell:
- Logging-Konfigurator
- CLI-Runner
- (Application-Service — Platzhalter, wird in AP09 feingeschnitten)
- ruft `CliRunner.run(args)` auf, gibt den zurückgegebenen Exit-Code an `System.exit` weiter
### CLI-Adapter
- Klasse `CliRunner` im Paket `adapter.in.cli`
- Methode `int run(String[] args)`
- akzeptiert **genau ein Positionsargument**: den Pfad zur Eingabedatei
- bei 0 oder ≥2 Argumenten → Exit-Code `2`, Minimalbericht-Vorbereitung (vollständige Minimalbericht-Logik kommt in AP08)
- bei nicht existierender, nicht lesbarer oder nicht regulärer Eingabedatei → Exit-Code `2`
- bei erfolgreichem Lauf ohne Spec-Fehler → Exit-Code `0`
- bei erfolgreichem Lauf mit Spec-Fehlern → Exit-Code `1`
### Exit-Code-Konstanten
- Konstanten **nur noch in einer Klasse** (z.B. `ExitCode` im Paket `adapter.in.cli`)
- Werte:
- `0` = gültig, keine Fehler-Befunde
- `1` = ungültig, mindestens ein Spec-Fehler
- `2` = Bedienfehler
- Die alten Konstanten (`EXIT_CODE_INVALID_ARGUMENTS=1`, `EXIT_CODE_FILE_ERROR=2`, `EXIT_CODE_VALIDATION_ERRORS=3`) werden **gelöscht**
### Verdrahtung mit Befundmodell (AP05)
- `CliRunner` gibt am Ende einen `ValidationReport` aus AP05 weiter oder erzeugt selbst einen Minimal-`ValidationReport` mit einem `Finding` des Kinds `SPEC`, Severity `ERROR`, Layer `ARTIFACT` im Bedienfehlerfall
- das eigentliche Einlesen und Verarbeiten der Datei kann für M1 noch ein **Dummy-Pfad** sein: die Datei wird gelesen, die Bytes gezählt, ein leerer `ValidationReport` mit `fileName` und `timestamp` zurückgegeben. Echte Validierung gehört nicht in M1.
### Zeichensatz-Korrektur
- beim Einlesen der Eingabedatei wird **ISO 8859-15** verwendet, nicht UTF-8. Das ist eine harte Spec-Vorgabe aus `fachliche-anforderungen.md` §5.1 und muss ab jetzt dauerhaft so bleiben.
```java
Files.readString(path, StandardCharsets.ISO_8859_1); // nicht ideal — besser Charset.forName("ISO-8859-15")
```
Achtung: Java kennt `StandardCharsets.ISO_8859_1`, aber **nicht** `ISO_8859_15`. Daher `Charset.forName("ISO-8859-15")` verwenden.
## Scope OUT
- Berichtdatei und Log-Datei im Eingabeverzeichnis (AP07)
- vollständiger Minimalbericht bei Exit-Code `2` (AP08)
- Entkopplung der Altlogik (AP09)
- Architekturtest (AP10)
## Schritte
1. Branch `m1/ap06-bootstrap-cli`
2. `de.gecheckt.asv.bootstrap.Main` anlegen mit `public static void main`
3. `CliRunner` in `adapter.in.cli` anlegen
4. `ExitCode`-Konstantenklasse anlegen
5. `AsvValidatorApplication` schrittweise entkernen: Code wandert nach `CliRunner` und `Main`
6. Einlese-Encoding auf `Charset.forName("ISO-8859-15")` umstellen
7. `maven-jar-plugin` in `pom.xml` auf `de.gecheckt.asv.bootstrap.Main` setzen (Platzhalter aus AP02 konkretisieren)
8. Alle Tests, die auf `AsvValidatorApplication` direkt zeigen, auf `CliRunner` umziehen
9. `mvn clean package` laufen lassen, das erzeugte JAR manuell mit `java -jar target/asv-format-validator-*.jar <test-datei>` prüfen
10. `mvn clean verify` grün bekommen
11. Commit `M1-AP06: Bootstrap, CLI-Adapter, Exit-Codes 0/1/2, ISO 8859-15`
12. Abschlussbericht schreiben
## Abnahmekriterien
- `de.gecheckt.asv.bootstrap.Main` existiert und ist `Main-Class` des JAR
- `CliRunner` ist der einzige Ort mit CLI-Argument-Parsing
- Exit-Codes `0`, `1`, `2` sind definiert und spec-konform eingesetzt
- **Test:** Aufruf ohne Argument → Exit-Code `2`
- **Test:** Aufruf mit nicht existierender Datei → Exit-Code `2`
- **Test:** Aufruf mit leerer, lesbarer Datei → Exit-Code `0` (Dummy-Pfad, leerer `ValidationReport`)
- Einlese-Encoding ist ISO 8859-15 (per Test belegt: eine Datei mit Byte `0xA4` ergibt beim Einlesen ``, weil `0xA4` in ISO 8859-15 auf Euro-Zeichen liegt)
- ausführbares JAR unter `target/` ist manuell startbar
- `mvn clean verify` ist grün
- Abschlussbericht liegt vor
## Rest-Risiken und offene Punkte
- Der Dummy-Pfad (Datei wird gelesen, leerer Report zurückgegeben) ist bewusst dünn. Die Einbindung der alten Parser-Logik passiert in AP09.
- Es ist verlockend, schon hier in AP06 die bestehende Parser-/Validator-Kette mit dem neuen Modell zu verknüpfen. **Nicht tun.** AP06 soll nur die äußere Hülle geradeziehen.
## Bericht
`docs/arbeitspakete/m1/berichte/AP06-bericht.md` nach `templates/ap-bericht.md`.

View File

@@ -0,0 +1,82 @@
# AP07 Ausgabeartefakte: Berichtdatei und Log-Datei mit Suffix-Logik
## Ziel
Pro Lauf werden **zwei Ausgabedateien** im **Verzeichnis der Eingabedatei** erzeugt:
- eine **Berichtdatei** `<basename>.txt`
- eine **Log-Datei** `<basename>.log`
Beide in **UTF-8**. Zusätzlich wird der Bericht weiterhin in die **Konsole** geschrieben. Wenn bereits gleichnamige Dateien existieren, werden neue mit laufendem Suffix `_v1`, `_v2`, … erzeugt, **pro Eingabedatei-Basisname**.
## Voraussetzungen
- AP04 (Logging-Adapter), AP05 (Befundmodell), AP06 (Bootstrap/CLI)
## Scope IN
### Berichtdatei
- Klasse `ReportFileWriter` oder ähnlich im Paket `adapter.out.reporting`
- Eingabe: `ValidationReport` (aus AP05) und Eingabedatei-Pfad
- Ausgabe: eine UTF-8-Textdatei im **selben Verzeichnis** wie die Eingabedatei
- Dateiname: `<basename-der-eingabedatei>.txt`, bei Konflikt `<basename>_v1.txt`, `<basename>_v2.txt`, …
- Inhalt für M1: **einfach gehalten**. Pro `Finding` eine Zeile mit den wichtigsten Metadaten (Severity, Kind, Layer, Feld-ID, deutsche Nachricht). Kopfzeile mit Dateiname, Zeitstempel, Verdict. Die fein strukturierte hierarchische Darstellung kommt erst in M9.
### Log-Datei
- Wiederverwendung des `LoggingConfigurator` aus AP04
- Methode `configureLogFile(Path logFile)` wird im Bootstrap **vor** dem CLI-Runner aufgerufen
- Log-Datei liegt im **selben Verzeichnis** wie die Eingabedatei
- Dateiname: `<basename>.log`, Suffix-Logik analog zur Berichtdatei
- Log4j2 wird programmatisch umkonfiguriert: der File-Appender schreibt nach dem neuen Pfad. Die statische `log4j2.xml` aus AP04 ist nur der Fallback für „kein Eingabeargument".
### Suffix-Logik
- eigene kleine Utility-Klasse `SuffixResolver` im Paket `adapter.out.filesystem`
- Methode `Path resolveNextFreePath(Path baseDirectory, String baseName, String extension)`:
- probiert `<baseName>.<ext>`, dann `<baseName>_v1.<ext>`, `<baseName>_v2.<ext>`, …
- gibt den ersten freien Pfad zurück
- wird sowohl für die Berichtdatei als auch für die Log-Datei verwendet
- **Hinweis:** Die Zählung ist pro Basisname unabhängig. Wenn für `test.auf.txt` schon `test.auf_v1.txt` existiert, aber für `test.auf.log` noch keine `_v1`, kann das vorkommen — die Suffixe müssen **nicht synchron** sein.
### Konsolenausgabe
- bleibt erhalten, schreibt denselben Bericht-Text wie die Berichtdatei
- Konsolenausgabe erfolgt **nach** der Berichtdatei-Erstellung, damit ein IO-Fehler beim Schreiben der Berichtdatei nicht die Konsolenausgabe verhindert
## Scope OUT
- hierarchische Berichtsgliederung (M9)
- Einfärbung / ANSI-Codes in der Konsole
- Log-Rotation
- Minimalbericht bei Exit-Code 2 (AP08)
## Schritte
1. Branch `m1/ap07-ausgabeartefakte`
2. `SuffixResolver` implementieren inkl. Unit-Tests für: keine Datei vorhanden, `.txt` vorhanden, `.txt` + `_v1` vorhanden, mehrere Lücken
3. `ReportFileWriter` implementieren mit einfachem Zeilenformat für M1
4. `LoggingConfigurator.configureLogFile(Path)` implementieren (programmatische Log4j2-Reconfiguration)
5. Bootstrap erweitern: vor CLI-Lauf → Log-Datei-Pfad bestimmen → `LoggingConfigurator` aufrufen
6. CLI-Runner erweitert: nach Lauf → Berichtdatei schreiben → Konsolenausgabe erzeugen
7. End-to-End-Test mit Dummy-Eingabedatei: beide Ausgabedateien entstehen, Suffix-Logik funktioniert
8. `mvn clean verify` grün
9. Commit `M1-AP07: Berichtdatei und Log-Datei im Eingabeverzeichnis mit Suffix-Logik`
10. Abschlussbericht schreiben
## Abnahmekriterien
- nach einem Lauf mit Eingabedatei `foo/bar.auf` existieren `foo/bar.auf.txt` und `foo/bar.auf.log`
- zweiter Lauf mit derselben Eingabedatei erzeugt `foo/bar.auf_v1.txt` und `foo/bar.auf_v1.log`
- dritter Lauf → `_v2` usw.
- beide Ausgabedateien sind UTF-8
- Konsolenausgabe ist identisch zum Inhalt der Berichtdatei
- `SuffixResolver` hat mindestens vier Unit-Tests
- `mvn clean verify` ist grün
- Abschlussbericht liegt vor
## Rest-Risiken und offene Punkte
- **Race Conditions** bei gleichzeitigen Läufen auf derselben Eingabedatei: laut `technik-und-architektur.md` bewusst nicht behandelt (kein Mehrbenutzerbetrieb in V1).
- Die programmatische Log4j2-Reconfiguration ist technisch nicht ganz ohne. Falls sie sich als zu instabil erweist, ist eine **sys-property-basierte** Konfiguration der Log-Datei (`-Dasv.log.file=...`) ein zulässiger Fallback. Entscheidung im Bericht dokumentieren.
- Das Bericht-Dateiformat ist in M1 absichtlich primitiv. In M9 wird es durch die finale hierarchische Struktur ersetzt.
## Bericht
`docs/arbeitspakete/m1/berichte/AP07-bericht.md` nach `templates/ap-bericht.md`.

View File

@@ -0,0 +1,80 @@
# AP08 Minimalbericht bei Bedienfehlern (Exit-Code 2)
## Ziel
Auch bei **Bedien- oder Zugriffsfehlern** (Exit-Code `2`) soll ein **Minimalbericht** entstehen, der den Fehler nachvollziehbar beschreibt. Das verlangt `technik-und-architektur.md` ausdrücklich: „Auch bei Exit-Code 2 soll, soweit technisch möglich, ein Minimalbericht erzeugt werden, der den Bedien- oder Zugriffsfehler nachvollziehbar beschreibt."
## Voraussetzungen
- AP06 (CLI), AP07 (Ausgabeartefakte)
## Scope IN
### Bedienfehler-Fälle
Alle diese Fälle müssen in Exit-Code `2` mit Minimalbericht resultieren:
1. **Kein Argument übergeben** → Minimalbericht auf Konsole (Eingabeverzeichnis unbekannt, also keine Dateiausgabe möglich)
2. **Mehr als ein Argument** → Minimalbericht auf Konsole
3. **Eingabedatei existiert nicht** → Minimalbericht auf Konsole und falls möglich in das übergeordnete Verzeichnis (dort wo die Datei hätte liegen sollen), sonst nur Konsole
4. **Eingabepfad ist kein regulärer Dateityp** (z.B. Verzeichnis) → Minimalbericht auf Konsole, keine Dateiausgabe
5. **Eingabedatei ist nicht lesbar** (Permissions) → Minimalbericht auf Konsole, Dateiausgabe wird versucht wenn Zielverzeichnis schreibbar ist, sonst nur Konsole
### Minimalbericht-Inhalt
Der Minimalbericht ist ein **`ValidationReport`** (aus AP05) mit:
- `fileName` = übergebener Pfad (oder Platzhalter `<kein Argument>` bzw. `<mehrere Argumente>`)
- `timestamp` = jetzt
- genau ein `Finding`:
- `kind = SPEC`
- `severity = ERROR`
- `layer = ARTIFACT`
- `ruleId = "OPERATIONAL-<fallkennung>"` (z.B. `OPERATIONAL-MISSING-ARG`, `OPERATIONAL-FILE-NOT-FOUND`, `OPERATIONAL-NOT-READABLE`, `OPERATIONAL-NOT-REGULAR`, `OPERATIONAL-TOO-MANY-ARGS`)
- `germanMessage` = kurzer, verständlicher deutscher Text
- **wichtig:** das Verdict dieses Reports ist **nicht** `INVALID`, sondern `OPERATIONAL_ERROR`. Die `Verdict`-Ableitungslogik muss in AP05 bereits den Fall „nur OPERATIONAL-Findings" erkennen können — falls das in AP05 noch nicht vorgesehen wurde, muss `ValidationReport` hier minimal erweitert werden.
- Alternative, sauberere Modellierung: ein zusätzlicher Konstruktor oder Factory-Methode `ValidationReport.operationalError(String fileName, String ruleId, String message)`, der den Verdict-Status explizit auf `OPERATIONAL_ERROR` setzt.
### Dateiausgabe bei Exit-Code 2
- wenn das Zielverzeichnis ermittelbar und schreibbar ist: Berichtdatei wird gemäß AP07-Logik erzeugt
- wenn nicht: **nur Konsolenausgabe**, keine Fehlermeldung („Bericht konnte nicht geschrieben werden"), weil das den Benutzer doppelt verunsichert
- eine kurze Hinweiszeile auf der Konsole ist okay: „Bericht konnte nicht in das Verzeichnis geschrieben werden, siehe Konsolenausgabe oben."
### Logging
- der Minimalbericht wird zusätzlich **geloggt** (`logger.error(...)`) — damit in der Log-Datei (sofern erzeugt) dokumentiert ist, was schiefging
- bei Fall 1 und 2 (keine Dateipfadinformation) ist die Log-Datei nicht sinnvoll zu platzieren → Fallback auf `log4j2.xml`-Default aus AP04
## Scope OUT
- Unterscheidung zwischen verschiedenen IO-Exceptions im Detail (`FileSystemException`, `AccessDeniedException`, …) — ein einheitlicher Fall „nicht lesbar" reicht
- Internationalisierung
- Exit-Codes jenseits von `0/1/2`
- Behandlung von `OutOfMemoryError`, `StackOverflowError` etc.
## Schritte
1. Branch `m1/ap08-minimalbericht`
2. Factory-Methode `ValidationReport.operationalError(...)` in AP05-Modell ergänzen (falls noch nicht vorhanden)
3. `CliRunner` um die fünf Bedienfehler-Fälle erweitern; pro Fall wird der passende Minimalbericht erzeugt
4. `ReportFileWriter`: im OPERATIONAL-Fall weichere IO-Fehlerbehandlung (keine `RuntimeException`, stattdessen Konsolenhinweis)
5. Unit-Tests für alle fünf Fälle
6. End-to-End-Test: `java -jar ... /pfad/zu/nichtvorhandener/datei.auf` erzeugt auf Konsole einen Minimalbericht und Exit-Code `2`
7. `mvn clean verify` grün
8. Commit `M1-AP08: Minimalbericht bei Exit-Code 2`
9. Abschlussbericht schreiben
## Abnahmekriterien
- alle fünf Bedienfehler-Fälle erzeugen einen Minimalbericht (per Unit-Test belegt)
- Exit-Code in allen fünf Fällen ist `2`
- Im Fall „Eingabedatei existiert nicht" wird der Minimalbericht in das übergeordnete Verzeichnis geschrieben, sofern dieses schreibbar ist
- Im Fall „kein Argument" wird der Minimalbericht **nur** auf Konsole ausgegeben (keine Dateiausgabe)
- `Verdict.OPERATIONAL_ERROR` ist in mindestens einem Test verifiziert
- `mvn clean verify` ist grün
- Abschlussbericht liegt vor
## Rest-Risiken und offene Punkte
- Im Fall „Eingabedatei existiert nicht, Zielverzeichnis aber schon" ist der Bericht-Basisname der **angegebene** Dateiname (obwohl die Datei nicht existiert). Das ist okay — der Benutzer findet den Bericht dort, wo er die Datei erwartet hätte.
- Die Unterscheidung zwischen `OPERATIONAL_ERROR` und `INVALID` im Verdict ist wichtig für spätere Reporting-Logik. Falls sich herausstellt, dass `OPERATIONAL_ERROR` als separater Verdict-Wert zu Komplikationen führt, kann alternativ ein Boolean-Flag `isOperational` auf dem Report verwendet werden. Entscheidung im Bericht dokumentieren.
## Bericht
`docs/arbeitspakete/m1/berichte/AP08-bericht.md` nach `templates/ap-bericht.md`.

View File

@@ -0,0 +1,86 @@
# AP09 Altlogik aus M1 entkoppeln (Parser/Validator einfrieren)
## Ziel
Die **bereits vorhandene Parser- und Validator-Logik** aus der früheren Implementierung (vor dieser M1-Planung) wird **nicht gelöscht**, aber sauber **entkoppelt** vom aktiven M1-Lauf. Sie wird als „Vorbau für M3 und folgende" explizit markiert und ist während M1 **nicht** Bestandteil der aktiven Verarbeitungskette.
Hintergrund: Der ursprüngliche Stand im Repository enthält bereits `DefaultInputFileParser`, `DefaultSegmentLineTokenizer`, `DefaultStructureValidator`, `DefaultFieldValidator`, `DefaultInputFileValidator` und `validation.model.ValidationResult`. Das ist wertvoll und darf nicht verloren gehen — gehört aber fachlich in M3 (Parser), M5 (Feldregeln) und M6 (Beziehungen), nicht in M1.
## Voraussetzungen
- AP03 (Migration), AP05 (neues Befundmodell), AP06 (neuer Bootstrap/CLI)
## Scope IN
### Einfrieren statt Löschen
- Die bestehenden Klassen bleiben **vollständig erhalten**, inklusive Tests
- Sie werden in ein klar erkennbares Unterpaket verschoben, z.B.:
```
de.gecheckt.asv.legacy.parser
de.gecheckt.asv.legacy.validation
de.gecheckt.asv.legacy.model
```
oder alternativ:
```
de.gecheckt.asv.application.preview
```
Die Entscheidung zwischen `legacy` und `preview` wird im Bericht dokumentiert und begründet. Empfehlung: **`preview`**, weil „legacy" suggeriert, dass etwas alt und zu entsorgen ist — tatsächlich wird der Code in M3/M5/M6 weiterverwendet.
- Jedes Paket bekommt ein `package-info.java` mit deutlichem Hinweis:
```
Diese Klassen stammen aus einer früheren Implementierung und sind
für die Meilensteine M3 bis M6 vorgesehen. Sie sind in M1 nicht Teil
der aktiven Validierungskette. Änderungen an diesen Klassen während
M1 sind zu vermeiden.
```
### Entkopplung vom Lauf
- `CliRunner` und `Bootstrap` dürfen die Preview-Klassen **nicht** aufrufen
- der aktive M1-Lauf verwendet ausschließlich den Dummy-Pfad aus AP06 (Datei einlesen, leeren `ValidationReport` erzeugen)
- die alten Tests der Preview-Klassen laufen **weiterhin grün mit**, damit der Code nicht verrottet
- `validation.model.ValidationResult` (alt) bleibt im Preview-Paket und wird **nicht** mit dem neuen `ValidationReport` aus AP05 verwechselt
### Saubere Kennzeichnung
- In `README.md` des Repos (falls vorhanden, sonst anlegen) ein kurzer Abschnitt „Preview-Code" mit Verweis auf `docs/arbeitspakete/m1/AP09-altlogik-einfrieren.md`
- Kein `@Deprecated`! Deprecated würde bedeuten „wird entfernt" — das Gegenteil ist der Fall.
## Scope OUT
- Weiterentwicklung der Preview-Klassen
- Änderung der Preview-Tests (außer notwendige Import-Anpassungen durch den Package-Umzug)
- Integration der Preview-Klassen in die neue `domain.finding`-Struktur (das ist explizit M3+)
- Löschung von Preview-Klassen, auch wenn sie wie Duplikate wirken
## Schritte
1. Branch `m1/ap09-preview-einfrieren`
2. Zielpaket wählen (`preview` empfohlen) und im Bericht begründen
3. Alle Parser-Klassen verschieben
4. Alle Validator-Klassen verschieben
5. `validation.model.ValidationResult` und `validation.model.*` mit verschieben
6. Tests entsprechend verschieben; Imports anpassen
7. `CliRunner`/`Bootstrap` auf Preview-Imports prüfen — **darf keine haben**, sonst entkoppeln
8. `package-info.java` mit Warnhinweis in jedem Preview-Unterpaket anlegen
9. README-Abschnitt „Preview-Code" ergänzen
10. `mvn clean verify` grün bekommen (alle Tests der Preview-Klassen laufen weiter mit)
11. Commit `M1-AP09: Alt-Parser und Alt-Validator nach preview-Paket, vom M1-Lauf entkoppelt`
12. Abschlussbericht schreiben
## Abnahmekriterien
- alle ursprünglich vorhandenen Parser- und Validator-Klassen liegen im Preview-Paket
- alle zugehörigen Tests laufen weiterhin grün
- `grep -rn "de.gecheckt.asv.preview" src/main/java/de/gecheckt/asv/adapter src/main/java/de/gecheckt/asv/bootstrap src/main/java/de/gecheckt/asv/application` ist **leer** (keine Referenzen aus dem aktiven Code)
- `package-info.java` mit Warnhinweis in jedem Preview-Unterpaket
- README enthält Abschnitt „Preview-Code"
- keine Klasse wurde gelöscht (`git log --diff-filter=D` für diesen Commit zeigt nur Verschiebungen)
- `mvn clean verify` ist grün
- Abschlussbericht liegt vor
## Rest-Risiken und offene Punkte
- Bei Wiederaufnahme in M3 wird zu klären sein, wie der Preview-Code an das neue Befundmodell angebunden wird. Das ist explizit M3-Aufgabe, nicht M1.
- Falls die Preview-Tests beim Package-Umzug brechen (wegen relativer Ressourcenpfade o.ä.), müssen sie einmalig angepasst werden. Das ist kein Scope-Verstoß, sondern Teil des Umzugs.
## Bericht
`docs/arbeitspakete/m1/berichte/AP09-bericht.md` nach `templates/ap-bericht.md`.

View File

@@ -0,0 +1,110 @@
# AP10 Architekturtest
## Ziel
Ein **automatisierter Architekturtest** stellt sicher, dass die in M1 etablierten Strukturregeln auch in Zukunft eingehalten werden. Insbesondere darf:
1. die **Log4j2-Bindung** nur in `adapter.out.logging` und `bootstrap` sichtbar sein
2. das `domain`-Paket **nichts** aus Adaptern oder Infrastruktur importieren
3. das `application`-Paket **nichts** aus konkreten Adaptern importieren, sondern nur aus `domain` und eigenen Ports
4. **Preview-Code** nicht aus dem aktiven Code (Bootstrap, CLI-Adapter, Application) referenziert werden
## Voraussetzungen
- AP04 (Logging-Adapter), AP09 (Preview eingefroren)
## Scope IN
### Technische Umsetzung
- **ArchUnit** (`com.tngtech.archunit:archunit-junit5`) als Test-Dependency aufnehmen
- neue Test-Klasse `ArchitectureTest` im Paket `de.gecheckt.asv` im Testbereich
- vier Tests:
### Test 1: Log4j2-Sichtbarkeit
```java
@ArchTest
static final ArchRule log4j2_nur_in_logging_adapter_und_bootstrap =
noClasses()
.that().resideOutsideOfPackages(
"de.gecheckt.asv.adapter.out.logging..",
"de.gecheckt.asv.bootstrap..")
.should().dependOnClassesThat()
.resideInAPackage("org.apache.logging.log4j..")
.because("Log4j2 darf nur im Logging-Adapter und im Bootstrap sichtbar sein.");
```
### Test 2: Domain ist frei
```java
@ArchTest
static final ArchRule domain_hat_keine_adapter_abhaengigkeit =
noClasses()
.that().resideInAPackage("de.gecheckt.asv.domain..")
.should().dependOnClassesThat()
.resideInAnyPackage(
"de.gecheckt.asv.adapter..",
"de.gecheckt.asv.bootstrap..",
"de.gecheckt.asv.preview..");
```
### Test 3: Application ist frei von konkreten Adaptern
```java
@ArchTest
static final ArchRule application_kennt_keine_adapter_implementierungen =
noClasses()
.that().resideInAPackage("de.gecheckt.asv.application..")
.should().dependOnClassesThat()
.resideInAnyPackage(
"de.gecheckt.asv.adapter..",
"de.gecheckt.asv.bootstrap..");
```
### Test 4: Preview wird nicht referenziert
```java
@ArchTest
static final ArchRule preview_wird_nicht_aus_aktivem_code_referenziert =
noClasses()
.that().resideInAnyPackage(
"de.gecheckt.asv.adapter..",
"de.gecheckt.asv.application..",
"de.gecheckt.asv.bootstrap..",
"de.gecheckt.asv.domain..")
.should().dependOnClassesThat()
.resideInAPackage("de.gecheckt.asv.preview..")
.because("Preview-Code ist aus M1-Sicht eingefroren und wird erst ab M3 aktiv verwendet.");
```
### Zusätzlich: Paketstruktur-Check
- Prüfen, dass die Soll-Pakete aus `technik-und-architektur.md` tatsächlich existieren (als ArchUnit-Regel oder einfacher Dateisystem-Test)
## Scope OUT
- komplexere Regeln wie „keine zyklischen Abhängigkeiten zwischen Paketen" — wäre schön, ist aber für M1 zu weitgehend
- Regeln zu Klassenbenennung
- Regeln zu `public`-Sichtbarkeit
- Tests für Preview-internen Aufbau
## Schritte
1. Branch `m1/ap10-architekturtest`
2. ArchUnit in `pom.xml` als Test-Dependency aufnehmen
3. `ArchitectureTest`-Klasse im Testbereich anlegen
4. Die vier Regeln implementieren
5. `mvn clean verify` laufen lassen — die Tests müssen **grün** sein. Falls rot: **das heißt, eine frühere M1-Phase hat die Regel verletzt**. Die Verletzung muss gefunden und behoben werden (kein Entschärfen der Regel!).
6. Commit `M1-AP10: Architekturtest für Log4j2-Sichtbarkeit, Paketabhängigkeiten, Preview-Isolation`
7. Abschlussbericht schreiben
## Abnahmekriterien
- ArchUnit ist als Test-Dependency eingebunden
- vier Architektur-Regeln sind implementiert und grün
- `mvn clean verify` ist grün
- Abschlussbericht liegt vor und dokumentiert, ob beim ersten Lauf Regeln rot waren und wenn ja, wie sie behoben wurden
## Rest-Risiken und offene Punkte
- ArchUnit hat beim ersten Einsatz manchmal Überraschungen mit transitiven Abhängigkeiten (Regel greift auch auf Framework-Klassen, die nicht gemeint waren). In dem Fall: Regel präzisieren, **nicht** ausschalten.
- Die Regel „Log4j2-Sichtbarkeit" schließt auch den Bootstrap mit ein. Wenn der Bootstrap später (M8) Krypto-Typen referenziert, müssen analoge Regeln ergänzt werden — aber das ist M8-Thema.
## Bericht
`docs/arbeitspakete/m1/berichte/AP10-bericht.md` nach `templates/ap-bericht.md`.

View File

@@ -0,0 +1,92 @@
# AP11 M1-Abnahme
## Ziel
Der letzte Schritt in M1: Alles wird gegen die Meilenstein-Abnahmekriterien aus `docs/specs/meilensteine.md` v3 **geprüft**, ein **End-to-End-Lauf** mit einer Minimal-Eingabedatei wird durchgeführt, und alle AP-Berichte werden in einem **konsolidierten M1-Abschlussbericht** zusammengeführt.
## Voraussetzungen
- AP01 bis AP10 abgeschlossen und grün
- alle AP-Berichte liegen in `docs/arbeitspakete/m1/berichte/` vor
## Scope IN
### End-to-End-Lauf
1. **Minimaldatei erstellen**: eine einfache Dummy-Textdatei im ISO-8859-15-Encoding, z.B. `test-artefakte/m1/minimal.txt` mit ein paar Zeilen Inhalt. Keine echten ASV-Daten, kein gültiges EDIFACT — dies ist nur ein Lauftest, kein Fachtest.
2. **JAR bauen**: `mvn clean package`
3. **Lauf 1**: `java -jar target/asv-format-validator-0.0.1-SNAPSHOT.jar test-artefakte/m1/minimal.txt`
- **Erwartung:** Exit-Code `0` (Dummy-Pfad, leerer Report), Berichtdatei `minimal.txt.txt` und Log-Datei `minimal.txt.log` entstehen, Konsolenausgabe vorhanden
4. **Lauf 2**: identischer Aufruf
- **Erwartung:** `minimal.txt_v1.txt` und `minimal.txt_v1.log` entstehen
5. **Lauf 3**: `java -jar ... nicht-vorhanden.txt`
- **Erwartung:** Exit-Code `2`, Minimalbericht auf Konsole, gegebenenfalls Berichtdatei im übergeordneten Verzeichnis wenn schreibbar
6. **Lauf 4**: `java -jar ...` (ohne Argument)
- **Erwartung:** Exit-Code `2`, Minimalbericht **nur** auf Konsole
7. **Lauf 5**: `java -jar ... datei1.txt datei2.txt`
- **Erwartung:** Exit-Code `2`, Minimalbericht auf Konsole
Alle fünf Läufe werden im M1-Abschlussbericht dokumentiert (Befehl, Exit-Code, relevante Ausgabe).
### Meilenstein-Abnahmeprüfung
Jeder Abnahmepunkt aus `docs/specs/meilensteine.md` v3 Abschnitt „Abnahme von M1" wird mit einem konkreten Nachweis verknüpft:
| M1-Abnahmekriterium | Nachweis | Status |
|---|---|---|
| Anwendung ist als JAR unter Windows mit Java 21 startbar | Lauf 1, JAR-Pfad | ✅ |
| falsches oder fehlendes Argument → Exit-Code `2` mit Minimalbericht | Lauf 3, 4, 5 | ✅ |
| Bericht- und Log-Datei werden im Eingabeverzeichnis mit korrekter Suffix-Logik erzeugt | Lauf 1 + Lauf 2 | ✅ |
| Log4j2-Bindung ist außerhalb von Bootstrap und Logging-Adapter nicht sichtbar | Architekturtest AP10, Test 1 | ✅ |
| Befundmodell unterscheidet Spec-Urteil und diagnostische Weiteranalyse | Unit-Test AP05 | ✅ |
| Build und Tests sind grün | `mvn clean verify` | ✅ |
### M1-Abschlussbericht
- Datei: `docs/arbeitspakete/m1/berichte/M1-abschlussbericht.md`
- Inhalt:
- **Zusammenfassung**: Was ist M1 geworden, in zwei Absätzen
- **AP-Übersicht**: Tabelle mit allen 11 APs, Status, Commit-Hashes, Abschlussdatum
- **Meilenstein-Abnahmetabelle** (siehe oben)
- **End-to-End-Protokoll**: die fünf Läufe mit Befehl, Exit-Code, Zusammenfassung der Ausgabe
- **Quality-Metriken** (Coverage, Testanzahl — **keine harten Gates in M1**, nur Informationswert)
- **Rest-Risiken und übertragene Punkte** aus allen AP-Berichten konsolidiert
- **Empfehlungen für M2**: Was sollte M2 beachten? Was ist aus M1-Sicht offen geblieben?
- **Commit-Graph-Snapshot**: `git log --oneline --graph main` für den M1-Zeitraum
- Freigabe-Vermerk am Ende: „M1 ist abnahmebereit" oder „M1 ist mit folgenden Einschränkungen abnahmebereit: ..."
### Tagging
- Git-Tag `m1-done` auf dem letzten AP11-Commit setzen
- Tag-Message: „Meilenstein 1 abgeschlossen, siehe docs/arbeitspakete/m1/berichte/M1-abschlussbericht.md"
## Scope OUT
- Vorgriffe auf M2-Themen (Dateinamensschemata, globale Rahmenregeln, ISO-8859-15 über Dateinamen hinaus — außer dem Einlese-Encoding aus AP06, das bleibt)
- Release-Builds, Signierung, Publizierung
- Externe Reviews (die kommen vom Rezensenten der Arbeitspakete, nicht aus diesem AP)
## Schritte
1. Branch `m1/ap11-abnahme`
2. Test-Artefakt `test-artefakte/m1/minimal.txt` anlegen (ISO-8859-15, 35 Zeilen Dummy-Inhalt)
3. `mvn clean package` ausführen
4. Die fünf Läufe durchführen und protokollieren
5. Konsolidierten M1-Abschlussbericht schreiben
6. `mvn clean verify` ein letztes Mal laufen lassen
7. Commit `M1-AP11: M1-Abnahme, End-to-End-Protokoll, konsolidierter Abschlussbericht`
8. Git-Tag `m1-done` setzen: `git tag -a m1-done -m "Meilenstein 1 abgeschlossen"`
## Abnahmekriterien
- `test-artefakte/m1/minimal.txt` existiert
- alle fünf Läufe sind protokolliert
- M1-Abschlussbericht existiert und enthält alle oben genannten Abschnitte
- Meilenstein-Abnahmetabelle ist vollständig und jede Zeile hat einen konkreten Nachweis
- `mvn clean verify` ist grün
- Git-Tag `m1-done` ist gesetzt
- der Freigabe-Vermerk am Ende des Abschlussberichts ist explizit
## Rest-Risiken und offene Punkte
- Dieser AP ist ein reines Zusammenfassungs-AP. Wenn hier Abnahmekriterien nicht erfüllt sind, zeigt das, dass ein früheres AP unvollständig war. In dem Fall: **zurück zum betroffenen AP**, nachbessern, dann AP11 wiederholen. Keine Abkürzungen.
## Bericht
`docs/arbeitspakete/m1/berichte/AP11-bericht.md` nach `templates/ap-bericht.md` **zusätzlich** zum konsolidierten `M1-abschlussbericht.md`.

View File

@@ -0,0 +1,83 @@
# M1 Arbeitspakete (Übersicht)
> **Bezug:** Meilenstein 1 aus `docs/specs/meilensteine.md` v3
> **Ziel:** tragfähiger technischer Sockel mit Logging-Adapter und Befundmodell (Spec-/Diagnose-Trennung); noch keine ASV-Fachvalidierung
> **Ist-Zustand:** Repo enthält bereits eine frühere, schichtenbasierte Implementierung mit Parser-, Validator- und Feldlogik (Commit `32d50ec` vom 27.03.2026). Diese muss erhalten, aber ins hexagonale Zielbild überführt werden.
> **Vorgehen:** **evolutionär, nicht in einem Wurf.** Jedes Arbeitspaket endet in einem grünen, stabilen Zwischenstand.
## Leitprinzipien für alle M1-Arbeitspakete
1. **So viel wie möglich aus dem Ist-Stand erhalten und refactoren**, nicht wegwerfen. Insbesondere Parser, Tokenizer und Validator-Gerüst sind wertvoll und gehören später in `adapter.out.parsing` bzw. `application`.
2. **Jedes Arbeitspaket endet mit einem Bericht** (`berichte/AP-MX-XX.md`) nach dem Schema in `templates/ap-bericht.md`.
3. **Jedes Arbeitspaket endet grün:** `mvn clean verify` muss durchlaufen. Build, Compile, Tests.
4. **Keine Fachvalidierung in M1.** Wer versucht, schon EDIFACT-Strukturprüfungen o.ä. einzubauen, verletzt den Scope. Bestehende Fachvalidierung darf erhalten bleiben, aber sie wird in M1 **nicht weiterentwickelt**.
5. **Commit-Strategie:** ein Commit pro Arbeitspaket, Commit-Message `M1-APxx: <Titel>`.
6. **Reviewbarkeit:** Der Bericht pro Arbeitspaket muss so präzise sein, dass ein unabhängiger Rezensent ohne Rückfragen prüfen kann, ob alles korrekt und in-scope umgesetzt wurde.
## Arbeitspaket-Folge
| AP | Titel | Hauptnutzen | Abhängigkeit |
|---|---|---|---|
| **AP01** | Ist-Stand-Inventar und Delta-Analyse | dokumentierter Ausgangspunkt, keine Überraschungen später | — |
| **AP02** | Build-Infrastruktur härten: SLF4J, JaCoCo, PIT, maven-jar-plugin, .editorconfig | `pom.xml` ist M1-tauglich, Quality-Gates messbar vorbereitet | AP01 |
| **AP03** | Hexagonale Paketstruktur anlegen und Ist-Code migrieren | Soll-Paketstruktur steht, bestehender Code ist eingeordnet, nichts geht kaputt | AP02 |
| **AP04** | Logging-Adapter (SLF4J-Fassade + Log4j2-Bindung) | Log4j2-Imports sind nur noch im Logging-Adapter und im Bootstrap sichtbar | AP03 |
| **AP05** | Befundmodell mit Spec-/Diagnose-Trennung (Domain) | `Finding`, `Severity`, `Verdict`, Metadata-Felder, strikt getrennt | AP03 |
| **AP06** | Bootstrap und CLI-Adapter: ein Positionsargument, Exit-Codes 0/1/2 | Exit-Codes sind spec-konform, Bootstrap verdrahtet manuell | AP05 |
| **AP07** | Ausgabeartefakte: Berichtdatei und Log-Datei im Eingabeverzeichnis mit Suffix-Logik | `.txt`/`.log` werden erzeugt, Suffix `_v1/_v2/...` funktioniert, UTF-8 | AP06 |
| **AP08** | Minimalbericht bei Exit-Code 2 (Bedienfehler) | auch bei fehlendem/falschem Argument oder nicht lesbarer Datei entsteht ein nachvollziehbarer Bericht | AP07 |
| **AP09** | Altlogik aus M1 entkoppeln: Parser/Validator in Adapter-/Application-Schicht eingefroren | bestehende Parser-/Validator-Logik ist erhalten, aber explizit als „Vorbau für M3+" markiert und nicht aktiv in den M1-Lauf verdrahtet | AP06 |
| **AP10** | Architekturtest: Log4j2-Sichtbarkeit, Paketabhängigkeiten, M1-Abnahme | ArchUnit-Test oder einfacher Klassenpfad-Scan stellt sicher, dass die Regeln eingehalten werden | AP04, AP09 |
| **AP11** | M1-Abnahme: grüner End-to-End-Lauf mit Minimaldatei, alle AP-Berichte konsolidiert | Meilenstein abgeschlossen, Übergabe an M2 möglich | alle vorigen |
## Verzeichnisstruktur (im Repo anzulegen)
```
docs/
arbeitspakete/
m1/
README.md (diese Datei)
templates/
ap-bericht.md (Berichtsvorlage)
AP01-ist-stand-inventar.md
AP02-build-infrastruktur.md
AP03-hexagonale-paketstruktur.md
AP04-logging-adapter.md
AP05-befundmodell.md
AP06-bootstrap-cli.md
AP07-ausgabeartefakte.md
AP08-minimalbericht.md
AP09-altlogik-einfrieren.md
AP10-architekturtest.md
AP11-m1-abnahme.md
berichte/
AP01-bericht.md (nach Abschluss)
AP02-bericht.md
...
```
## Grobumfang pro AP
Jedes Arbeitspaket hat eine eigene Datei mit:
- **Ziel** (was soll erreicht werden)
- **Voraussetzungen** (welche APs müssen abgeschlossen sein)
- **Scope IN** (was explizit Teil dieses APs ist)
- **Scope OUT** (was explizit NICHT Teil dieses APs ist)
- **Schritte** (konkrete Handlungsanleitung)
- **Abnahmekriterien** (messbar, reviewbar)
- **Rest-Risiken und offene Punkte** (was kann schiefgehen, was bleibt offen)
- **Berichtsschablone** (Hinweis, den Abschlussbericht nach `templates/ap-bericht.md` anzulegen)
## Definition of Done für den gesamten M1
Ein M1 ist abgenommen, wenn:
- alle 11 Arbeitspakete grün abgeschlossen sind
- für jedes Arbeitspaket ein Abschlussbericht in `docs/arbeitspakete/m1/berichte/` existiert
- die Anwendung als ausführbares JAR vorliegt und mit `java -jar asv-format-validator.jar <datei>` startbar ist
- die Exit-Codes 0/1/2 spec-konform sind
- Bericht- und Log-Datei im Eingabeverzeichnis erzeugt werden
- Log4j2-Typen außerhalb von Bootstrap und Logging-Adapter nicht mehr importiert werden (per Architekturtest nachweisbar)
- Befundmodell trennt Spec-Urteil und diagnostische Weiteranalyse
- `mvn clean verify` ist grün
- M1-Abnahmebericht (`AP11-bericht.md`) fasst alles zusammen

View File

@@ -0,0 +1,66 @@
# Abschlussbericht Arbeitspaket AP-XX-<Titel>
> **Bezug:** `docs/arbeitspakete/m1/APxx-<slug>.md`
> **Bearbeiter:** <Name / KI-Agent / Mensch>
> **Datum:** <YYYY-MM-DD>
> **Commit(s):** <Hash(es)>
> **Status:** ✅ abgeschlossen / ⚠️ abgeschlossen mit Einschränkungen / 🔴 abgebrochen
## 1. Zusammenfassung
Ein bis zwei Sätze: Was wurde gemacht?
## 2. Umgesetzte Änderungen
Konkrete Aufzählung der tatsächlich durchgeführten Änderungen. Wenn möglich mit Dateipfaden und kurzer Begründung.
- `pfad/zur/datei` was geändert wurde und warum
-
## 3. Scope-Treue
| Scope-Punkt aus dem Arbeitspaket | Erfüllt? | Bemerkung |
|---|---|---|
| Punkt 1 | ✅ / ⚠️ / ❌ | … |
| Punkt 2 | ✅ / ⚠️ / ❌ | … |
**Wurde der Scope eingehalten?** Ja / Nein / teilweise (begründen)
**Wurden Dinge außerhalb des Scopes gemacht?** Falls ja, welche und warum?
## 4. Abnahmekriterien
| Abnahmekriterium aus dem Arbeitspaket | Erfüllt? | Nachweis |
|---|---|---|
| Kriterium 1 | ✅ / ⚠️ / ❌ | z.B. Testname, Commit-Hash, Log-Ausschnitt |
| … | | |
## 5. Build- und Teststatus
- `mvn clean verify`: ✅ grün / 🔴 rot
- Anzahl Tests: N (davon M neu hinzugefügt)
- Coverage (falls bereits messbar): domain = X %, application = Y %, …
- Warnungen beim Build: keine / siehe unten
## 6. Rest-Risiken und offene Punkte
Was kann noch schiefgehen? Was wurde bewusst nicht gelöst und in ein späteres Arbeitspaket geschoben?
- Risiko 1: …
- Offener Punkt 1: …
## 7. Empfehlungen für Folge-Arbeitspakete
Was sollte das nächste AP beachten? Gibt es Lessons Learned?
## 8. Reviewer-Checkliste
Der Rezensent prüft damit die korrekte Umsetzung:
- [ ] Alle im Arbeitspaket genannten Scope-IN-Punkte sind nachweislich umgesetzt
- [ ] Keine Scope-OUT-Punkte wurden angefasst
- [ ] Abnahmekriterien sind mit konkreten Nachweisen belegt (Tests, Dateipfade, Commits)
- [ ] `mvn clean verify` ist grün
- [ ] Der Commit für dieses AP hat eine sprechende Message (`M1-APxx: ...`)
- [ ] Keine Regeln der Grunddokumente (Spec, Fachliche, Technik) wurden verletzt
- [ ] Rest-Risiken sind ehrlich dokumentiert