Files
pi_mcps/java/mss-failsafe/.github/architecture.instructions.md
T
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

76 lines
3.7 KiB
Markdown
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<E>)
3. Business: Stateless EJB Manager mit CRUD + Fachlogik (extends AbstractManager<T>)
4. Persistence: JPA Entities (extends AbstractEntity)
## Basisklassen Rollen
- AbstractEntity: Basis-ID (Long, Identity), Timestamps, outdated Flag, equals/hashCode nur über ID.
- AbstractManager<T>: CRUD, save vs saveAll, remove / removeAllIn, refresh (Hibernate.initialize), Fehlerlogging.
- AbstractController<E>: 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<E>) 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<NewEntity>; spezifische Queries / Reload Methoden.
3. Controller: @Named + Scope (ViewScoped/SessionScoped) extends AbstractController<NewEntity>.
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.
---