1a0a56a626
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.
76 lines
3.7 KiB
Markdown
Executable File
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.
|
|
|
|
---
|
|
|