ArchUnit-Prüfung nachschärfen (Review-Befunde Schritt 0, ADR 0033) #124

Open
opened 2026-10-20 14:04:16 +00:00 by claude · 2 comments
Collaborator

Aufgeschobene Befunde aus dem Abschluss-Review von feature/archunit (Schritt 0 aus ADR 0033, #120 Teil 1), 20.10.2026. Behoben ist bereits: Die Tabelle gilt nur noch in shared, competition und cms (ein viertes oder vertipptes Modul bestand vorher alle Regeln).

Offen, gewichtiger

  1. Store-Zuwachs in der CI prüfen. Der Schritt „Architektur-Store unveraendert“ merkt nur, wenn der Testlauf den Store ändert. Ein Store, der wächst und mitcommittet wird (-Darchunit.freeze.refreeze=true, Store neu anlegen, Regel umbenennen), kommt durch; heute fällt das nur im Review auf. Vorschlag: git diff --numstat <merge-base mit origin/main>..HEAD -- backend/src/test/archunit_store auf hinzugefügte Zeilen prüfen. Ein Schrumpfen erzeugt nur Löschungen (am ArchUnit-Bytecode belegt), Fehlalarme gäbe es also keine. Der Checkout ist --depth 1, main müsste nachgeladen werden. CLAUDE.md und archunit.properties sagen das Verbot schon ausdrücklich.
  2. Regeln ohne Altbestand nicht einfrieren? modules, domainWithoutTechnology und mailOnlyInNotifier haben 0 Einträge. Als gewöhnliche Regel könnte sie auch ein refreeze nicht aufweichen. Der Plan wollte sie eingefroren; das ist eine Entscheidung für Olli.

Offen, klein (Gegenprobe und Reichweite)

  1. Die zweite Teilregel von mailOnlyInNotifier („nur CaptainNotificationService benutzt NotificationMailer“) hat keine Fixture.
  2. Fixtures, die ArchUnit-Verhalten gegen spätere Upgrades festhalten: Methodenreferenz (Thing::findById) in noActiveRecord; Mengenzählung im Freeze (zwei gleichlautende Verstösse, einer eingefroren → rot); Zeilenverschiebung an einem Methodenaufruf mit echter Zeilennummer statt nur :0.
  3. onlyRepositoriesUseEntityManager prüft nur jakarta.persistence.EntityManager. org.hibernate.Session/StatelessSession, EntityManagerFactory und Panache.getEntityManager() gingen vorbei; heute kommt nichts davon vor.
  4. domainWithoutTechnology kennt org.jboss.resteasy.., org.eclipse.microprofile.., io.smallrye.. und io.vertx.. nicht. jakarta.annotation.. bewusst nicht dazu (#120 Teil 3, Nullability).
  5. Die Paketmuster stehen doppelt in layers() und everyClassHasARow(); ein Tippfehler in nur einer Liste bliebe wegen withOptionalLayers(true) still.

Abnahme

  • Ein committeter Store mit zusätzlicher Zeile macht die CI rot (Punkt 1), ein geschrumpfter nicht.
  • Für 3–6 je eine Fixture, die ohne die Änderung grün und mit ihr rot wäre bzw. umgekehrt.
Aufgeschobene Befunde aus dem Abschluss-Review von `feature/archunit` (Schritt 0 aus ADR 0033, #120 Teil 1), 20.10.2026. Behoben ist bereits: Die Tabelle gilt nur noch in `shared`, `competition` und `cms` (ein viertes oder vertipptes Modul bestand vorher alle Regeln). ## Offen, gewichtiger 1. **Store-Zuwachs in der CI prüfen.** Der Schritt „Architektur-Store unveraendert“ merkt nur, wenn der *Testlauf* den Store ändert. Ein Store, der wächst und mitcommittet wird (`-Darchunit.freeze.refreeze=true`, Store neu anlegen, Regel umbenennen), kommt durch; heute fällt das nur im Review auf. Vorschlag: `git diff --numstat <merge-base mit origin/main>..HEAD -- backend/src/test/archunit_store` auf hinzugefügte Zeilen prüfen. Ein Schrumpfen erzeugt nur Löschungen (am ArchUnit-Bytecode belegt), Fehlalarme gäbe es also keine. Der Checkout ist `--depth 1`, `main` müsste nachgeladen werden. CLAUDE.md und `archunit.properties` sagen das Verbot schon ausdrücklich. 2. **Regeln ohne Altbestand nicht einfrieren?** `modules`, `domainWithoutTechnology` und `mailOnlyInNotifier` haben 0 Einträge. Als gewöhnliche Regel könnte sie auch ein refreeze nicht aufweichen. Der Plan wollte sie eingefroren; das ist eine Entscheidung für Olli. ## Offen, klein (Gegenprobe und Reichweite) 3. Die zweite Teilregel von `mailOnlyInNotifier` („nur `CaptainNotificationService` benutzt `NotificationMailer`“) hat keine Fixture. 4. Fixtures, die ArchUnit-Verhalten gegen spätere Upgrades festhalten: Methodenreferenz (`Thing::findById`) in `noActiveRecord`; Mengenzählung im Freeze (zwei gleichlautende Verstösse, einer eingefroren → rot); Zeilenverschiebung an einem Methodenaufruf mit echter Zeilennummer statt nur `:0`. 5. `onlyRepositoriesUseEntityManager` prüft nur `jakarta.persistence.EntityManager`. `org.hibernate.Session`/`StatelessSession`, `EntityManagerFactory` und `Panache.getEntityManager()` gingen vorbei; heute kommt nichts davon vor. 6. `domainWithoutTechnology` kennt `org.jboss.resteasy..`, `org.eclipse.microprofile..`, `io.smallrye..` und `io.vertx..` nicht. `jakarta.annotation..` bewusst nicht dazu (#120 Teil 3, Nullability). 7. Die Paketmuster stehen doppelt in `layers()` und `everyClassHasARow()`; ein Tippfehler in nur einer Liste bliebe wegen `withOptionalLayers(true)` still. ## Abnahme - Ein committeter Store mit zusätzlicher Zeile macht die CI rot (Punkt 1), ein geschrumpfter nicht. - Für 3–6 je eine Fixture, die ohne die Änderung grün und mit ihr rot wäre bzw. umgekehrt.
Author
Collaborator

Entscheidung zu Punkt 2 (Olli, 20.10.2026): gewöhnliche Regeln statt eingefrorener. modules, domainWithoutTechnology und mailOnlyInNotifier haben keinen Altbestand. Als gewöhnliche Regel kann sie auch ein refreeze, ein neu angelegter Store oder eine Umbenennung nicht aufweichen. Findet eine davon später doch alte Fälle (etwa nach einer Verschärfung), wird sie dann eingefroren.

**Entscheidung zu Punkt 2 (Olli, 20.10.2026): gewöhnliche Regeln statt eingefrorener.** `modules`, `domainWithoutTechnology` und `mailOnlyInNotifier` haben keinen Altbestand. Als gewöhnliche Regel kann sie auch ein `refreeze`, ein neu angelegter Store oder eine Umbenennung nicht aufweichen. Findet eine davon später doch alte Fälle (etwa nach einer Verschärfung), wird sie dann eingefroren.
Author
Collaborator

Alle sieben Punkte sind in main (b1d9b28, README f477cc4; noch nicht gepusht).

Technische Abnahme: mvn -B clean verify grün (6359 Tests). CI-Lauf 1205 grün; der neue Schritt hat dort gegen den Abzweigpunkt 9f3387e verglichen. E2E auf Staging 214/214 (feature-archunit-nachschaerfen-b1d9b28, Lauf 409). metrics.py diff 0/0/0. Ein Review (Opus) ist eingearbeitet.

Was sich geändert hat

  1. Der CI-Schritt „Architektur-Store waechst nicht“ (scripts/archunit-store-check.sh) wird rot, wenn der Store gegenüber dem Abzweigpunkt von main wächst; auf main gilt der Stand vor dem Push. Verglichen wird je Regel, ohne Reihenfolge und mit Vielfachheit, denn ArchUnit verbraucht jede Store-Zeile einmal. Im Store stehen heute schon 110 doppelte Zeilen.

  2. Modulgrenzen, Fachkern und Mail sind gewöhnliche Regeln (Entscheidung oben), ihre leeren Store-Dateien sind weg.

  3. bis 6. Neue Fixtures:

    • die zweite Teilregel der Mail-Regel,
    • eine Methodenreferenz auf Active Record,
    • die Zählung im Freeze,
    • eine Zeilenverschiebung an einem Methodenaufruf.

    Die EntityManager-Regel kennt jetzt auch Session, SessionFactory, StatelessSession, EntityManagerFactory und Panache. Die Fachkern-Regel kennt auch resteasy, microprofile, smallrye und vertx. Gegen die alten Regeln sind beide neuen Fixtures rot.

  4. Die Pakete der Tabelle stehen nur noch an einer Stelle (rows()).

Bewusst offen

  • Bricht cancel-in-progress auf main den Lauf eines Pushes ab, prüft der nächste nur seinen eigenen Abschnitt. Ein Zuwachs fällt dann nur im vorherigen Lauf auf dem Branch auf. Das steht als Kommentar im CI-Schritt.
  • Zwei byte-gleiche Verstösse in derselben Zeile zählt ArchUnit selbst nicht.
  • Der Fall „Push auf main“ (Vergleich mit github.event.before) zeigt sich zum ersten Mal mit dem Push dieses Merges.

Prüfschritte (Olli)

  1. Nach dem Push von main: Im CI-Lauf zu f477cc4 meldet der Schritt „Architektur-Store waechst nicht“ ArchUnit-Store gegenueber 9f3387e nicht gewachsen. (Vergleich mit dem Stand vor dem Push).
  2. Lokal: scripts/archunit-store-check.sh main~2 meldet „nicht gewachsen“. Mit einer zusätzlichen Zeile in backend/src/test/archunit_store/b599773f-… (committet, danach zurücksetzen) meldet es „gewachsen, neue Eintraege: 1“ und Exit 1.
  3. backend/src/test/java/ch/sffs/tt/architecture/ArchitectureTest.java: Nur noch vier Regeln stehen in FreezingArchRule.freeze(...).
Alle sieben Punkte sind in `main` (`b1d9b28`, README `f477cc4`; noch nicht gepusht). **Technische Abnahme:** `mvn -B clean verify` grün (6359 Tests). CI-Lauf 1205 grün; der neue Schritt hat dort gegen den Abzweigpunkt `9f3387e` verglichen. E2E auf Staging 214/214 (`feature-archunit-nachschaerfen-b1d9b28`, Lauf 409). `metrics.py diff` 0/0/0. Ein Review (Opus) ist eingearbeitet. **Was sich geändert hat** 1. Der CI-Schritt **„Architektur-Store waechst nicht“** (`scripts/archunit-store-check.sh`) wird rot, wenn der Store gegenüber dem Abzweigpunkt von `main` wächst; auf `main` gilt der Stand vor dem Push. Verglichen wird je Regel, ohne Reihenfolge und **mit** Vielfachheit, denn ArchUnit verbraucht jede Store-Zeile einmal. Im Store stehen heute schon 110 doppelte Zeilen. 2. Modulgrenzen, Fachkern und Mail sind **gewöhnliche Regeln** (Entscheidung oben), ihre leeren Store-Dateien sind weg. 3. bis 6. Neue Fixtures: - die zweite Teilregel der Mail-Regel, - eine Methodenreferenz auf Active Record, - die Zählung im Freeze, - eine Zeilenverschiebung an einem Methodenaufruf. Die EntityManager-Regel kennt jetzt auch `Session`, `SessionFactory`, `StatelessSession`, `EntityManagerFactory` und `Panache`. Die Fachkern-Regel kennt auch resteasy, microprofile, smallrye und vertx. Gegen die alten Regeln sind beide neuen Fixtures rot. 7. Die Pakete der Tabelle stehen nur noch an einer Stelle (`rows()`). **Bewusst offen** - Bricht `cancel-in-progress` auf `main` den Lauf eines Pushes ab, prüft der nächste nur seinen eigenen Abschnitt. Ein Zuwachs fällt dann nur im vorherigen Lauf auf dem Branch auf. Das steht als Kommentar im CI-Schritt. - Zwei byte-gleiche Verstösse in derselben Zeile zählt ArchUnit selbst nicht. - Der Fall „Push auf `main`“ (Vergleich mit `github.event.before`) zeigt sich zum ersten Mal mit dem Push dieses Merges. **Prüfschritte (Olli)** 1. Nach dem Push von `main`: Im CI-Lauf zu `f477cc4` meldet der Schritt „Architektur-Store waechst nicht“ `ArchUnit-Store gegenueber 9f3387e nicht gewachsen.` (Vergleich mit dem Stand vor dem Push). 2. Lokal: `scripts/archunit-store-check.sh main~2` meldet „nicht gewachsen“. Mit einer zusätzlichen Zeile in `backend/src/test/archunit_store/b599773f-…` (committet, danach zurücksetzen) meldet es „gewachsen, neue Eintraege: 1“ und Exit 1. 3. `backend/src/test/java/ch/sffs/tt/architecture/ArchitectureTest.java`: Nur noch vier Regeln stehen in `FreezingArchRule.freeze(...)`.
Sign in to join this conversation.
No description provided.