Files
pi_mcps/java/mss-failsafe/.github/architecture.instructions.md
Patrick Plate 1a0a56a626 chore(java): consolidate mss-failsafe to single canonical copy
Replace the stale multi-module java/mss-failsafe skeleton (old user-management
prototype) with the active single-module machine-safety inspection app that was
living in its own standalone repo at the repo root.

- Remove old java/mss-failsafe/ multi-module tree (mss, userdata, userManagement,
  mssfailsafe.datalayer, mssfailsafeWeblayer) incl. committed build artifacts
- Add the active app (PrimeFaces 11 / JSF 2.3 / Hibernate 5.6 / iText / POI)
  flattened into java/mss-failsafe/ as the only mss-failsafe in git
- Working tree captured = master tip 2a142b5 + in-progress uncommitted work
  (incl. .github/*.instructions.md AI-context files)
- Archive the standalone repo's 33-commit history in GIT_HISTORY_ARCHIVE.md
  since its .git was not migrated

This is the source of truth / base for the upcoming upgraded rewrite.
2026-06-13 19:55:28 +02:00

3.7 KiB
Executable File

Architecture Instructions

Aktualisiert: 2025-10-20

Überblick

Das System folgt einer klassischen 4-Layer Struktur:

  1. View: JSF 2.3 / PrimeFaces 11 / XHTML Seiten (Formulare, Tabellen, Dialoge)
  2. Controller: CDI/JSF Managed Beans, Zustandsverwaltung & UI-Aktionen (extends AbstractController)
  3. Business: Stateless EJB Manager mit CRUD + Fachlogik (extends AbstractManager)
  4. Persistence: JPA Entities (extends AbstractEntity)

Basisklassen Rollen

  • AbstractEntity: Basis-ID (Long, Identity), Timestamps, outdated Flag, equals/hashCode nur über ID.
  • AbstractManager: CRUD, save vs saveAll, remove / removeAllIn, refresh (Hibernate.initialize), Fehlerlogging.
  • AbstractController: UI State (selected, created, entities), Fake-ID-Erzeugung für neue temporäre Objekte, Messaging, PDF Utilities.

Lebenszyklus eines neuen Objekts

  1. UI erzeugt neues Objekt (id == null) -> Controller kann negative Fake-ID setzen falls in Collections benötigt.
  2. Vor persist: Falls id < 0 -> setId(null) damit JPA Identity funktioniert.
  3. save(): id == null => persist + flush, sonst merge + flush.
  4. refresh(): sorgt für Managed Entity + Initialisierung Lazy Properties.

Negative Fake IDs

  • Zweck: Temporäre Unterscheidung mehrerer neu angelegter Einträge im UI bevor persist.
  • Erzeugung: createFakeID(Collection) nimmt kleinste vorhandene negative ID - 1.
  • Vor persist unbedingt auf null setzen.

Lazy Loading & Refresh

  • Manager.refresh(entity) -> merge + Hibernate.initialize(entity) für Entität.
  • Für Collections: spezielle Reload-Methoden in fachlichen Managern (z.B. reloadWithQuestionnaires).
  • Nach Batch-Operationen Controller.refrehSelected() (Tippfehler) nutzen; perspektivisch in refreshSelected() umbenennen.

Transaktionen

  • Schreiboperationen annotiert mit @Transactional (Container-managed) in AbstractManager.save / saveAll.
  • Fachmethoden, die persistieren oder mergen, sollten ebenfalls @Transactional erhalten (Konsistenz).

Fehlerbehandlung

  • Aktuell: Logging (LOGGER.error) + bool Rückgabe.
  • Geplant: Einführung BusinessException für differenzierte Fehlerpfade.

Erweiterungsmuster (Domain hinzufügen)

  1. Entity erstellen (extends AbstractEntity). Optional Named Queries.
  2. Manager: @Stateless extends AbstractManager; spezifische Queries / Reload Methoden.
  3. Controller: @Named + Scope (ViewScoped/SessionScoped) extends AbstractController.
  4. XHTML Seite inkl. Referenzen zu Controller (DataTable, Dialoge, Commands).
  5. Tests: CRUD & fachliche Spezialfunktionen.

Typische Fachfunktionen

  • Klonen: Quelle re-laden + initialisieren; neue Instanz mit Copy-Konstruktor; Child IDs null; Collections duplizieren kontrolliert.
  • Zuordnungen (z.B. Fragebogen): Add/Remove Pattern über Wrapper Entity.

PDF-Erstellung

  • iText7 Nutzung über Hilfsmethoden in AbstractController (Tabellen, Inner Cells, Paginierung).
  • Keine neuen Features mehr mit iText5 API implementieren.

Querschnittsthemen & Roadmap

  • Vereinheitlichte Exception Layer.
  • Bean Validation (javax.validation) für Eingaben & persistente Konsistenz.
  • Test Suite (JUnit + ggf. Arquillian / Integrationstests) ausbauen.
  • Migration nach Jakarta EE (Namespace Wechsel javax -> jakarta) perspektivisch.

Edge Cases & Hinweise

  • save(null) => false zurückgeben.
  • remove(entity) ohne persistierte ID => false.
  • Batch Speichern: leere Liste => true (no-op) statt Fehler.
  • Collections initialisieren vor Iteration (Avoid LazyInitializationException).

Generator Leitplanken

  • Bestehende Signaturen respektieren.
  • Keine neuen Frameworks ohne Notwendigkeit.
  • Logging immer via LOGGER, niemals System.out.
  • Für neue Write-Methoden @Transactional hinzufügen.