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.
This commit is contained in:
+102
@@ -0,0 +1,102 @@
|
||||
# Manager/Controller Pattern Instructions
|
||||
|
||||
Aktualisiert: 2025-10-20
|
||||
|
||||
## Ziele
|
||||
Klare Trennung zwischen UI-Zustand (Controller) und Geschäftslogik/Persistenz (Manager).
|
||||
|
||||
## Verantwortlichkeiten
|
||||
Controller:
|
||||
- Zustände: selected, created, entities.
|
||||
- UI Nachrichten (FacesMessage).
|
||||
- Dialogsteuerung (PrimeFaces Widgets schließen).
|
||||
- Hilfsfunktionen (PDF, Fake-ID-Erzeugung).
|
||||
|
||||
Manager:
|
||||
- CRUD Operationen (create, edit, save, saveAll, remove, removeAllIn, find, findAll).
|
||||
- Fachspezifische Queries / Reload.
|
||||
- Fehlerlogging.
|
||||
|
||||
## Interaktion
|
||||
- Controller ruft Manager.save / saveAll auf für Persistenz.
|
||||
- Nach Änderungen: Controller.refrehSelected() (Tippfehler) -> aktualisiert ausgewähltes Objekt.
|
||||
- Kein direkter EntityManager Zugriff im Controller.
|
||||
|
||||
## Fake-ID Ablauf
|
||||
1. Controller erzeugt neue Entität (id == null).
|
||||
2. Falls Sammlung benötigt: setzt negative ID über createFakeID.
|
||||
3. Bei Save: Manager erkennt id < 0 (nach vorherigem Nullsetzen) -> persist.
|
||||
|
||||
## Methoden-Namenskonventionen
|
||||
- Manager: Verb + Domänenobjekt (addQuestionnaireToSecurityArea, removeQuestionnaireFromSecurityArea).
|
||||
- Controller: UI Aktionen (saveSelected, createNew, openDialog, closeDialogs).
|
||||
|
||||
## Edge Cases
|
||||
- selected == null bei refresh -> no-op.
|
||||
- entities Liste leer -> UI Tabelle zeigt keine Einträge; Null vermeiden (immer leere Liste).
|
||||
|
||||
## Messaging
|
||||
- Erfolg: `successMessage()`; Fehler: `errorMessage()`.
|
||||
- Spezifische Warnungen über `sendWarnMessage`.
|
||||
|
||||
## Verbesserungen
|
||||
- Umbenennung `refrehSelected()` -> `refreshSelected()` in Basisklasse + alle Verwendungen.
|
||||
- Einführung eines BasePDFController oder Utility zur Auslagerung PDF Logik.
|
||||
|
||||
## Generator Leitplanken
|
||||
- Zusätzliche Logik (berechnete Felder, Validierungen) zuerst im Manager statt im Controller (besser testbar, wiederverwendbar).
|
||||
- Controller schlank halten: keine komplexe Businessregeln.
|
||||
|
||||
---
|
||||
# Persistence Instructions
|
||||
|
||||
Aktualisiert: 2025-10-20
|
||||
|
||||
## Ziele
|
||||
Konsistente JPA Nutzung (Java EE 8, Hibernate Provider) mit klaren Regeln für IDs, Lazy Loading und Flush.
|
||||
|
||||
## Grundsätze
|
||||
- Entities extend `AbstractEntity` (Long id, creationDate, changedDate, outdated Flag).
|
||||
- Identity Generation: `@GeneratedValue(strategy = GenerationType.IDENTITY)` -> Kein manuelles Setzen positiver IDs.
|
||||
- Equals/HashCode nur auf ID (Basis-Klasse bereitgestellt).
|
||||
|
||||
## ID & Fake-ID Handling
|
||||
- Temporäre neue Objekte können negative IDs erhalten (Fake) zur UI-Differenzierung.
|
||||
- Vor persist: if id != null && id < 0 -> `setId(null)` damit JPA eine echte ID generiert.
|
||||
- Niemals persist mit negativer ID ausführen.
|
||||
|
||||
## Lebenszyklus
|
||||
1. Konstruktor setzt creationDate & changedDate.
|
||||
2. Bei Änderungen Fachlogik: changedDate aktualisieren (TODO: zentralisieren via EntityListener).
|
||||
3. Persist -> flush direkt in `AbstractManager.save` / `saveAll`.
|
||||
|
||||
## Lazy Loading
|
||||
- Vermeide direkte Iteration über nicht initialisierte Collections außerhalb Transaktion.
|
||||
- Nutzung `AbstractManager.refresh(entity)` initialisiert das Entity (Hibernate.initialize(entity)).
|
||||
- Für Collections eigene Reload-Methoden in spezialisierten Managern implementieren.
|
||||
|
||||
## Named Queries & Criteria
|
||||
- Bevorzugt Criteria API für dynamische Filter.
|
||||
- Häufig verwendete, statische Abfragen als `@NamedQuery` in der Entity definieren.
|
||||
|
||||
## Performance Hinweise
|
||||
- `saveAll(Collection<T>)` nutzt einen Flush am Ende; reduziert DB Roundtrips.
|
||||
- Bulk Delete oder Update lieber über JPQL statt Einzelloops (aktuell: removeAllIn loop; Optimierungspotential).
|
||||
|
||||
## Edge Cases
|
||||
- `save(null)` => false (kein Fehlerwurf, Logging im Manager).
|
||||
- Leere Collections in `saveAll` => true (no-op).
|
||||
- `remove(entity)` mit `entity.getId()==null` => false; vorher persistieren oder ignorieren.
|
||||
|
||||
## Verbesserungs-Ideen
|
||||
- EntityListener für Timestamps.
|
||||
- Soft Delete (outdated Flag) statt physischem Löschen für Audit.
|
||||
- Einführung eines Version-Feldes für Optimistic Locking.
|
||||
|
||||
## Generator Leitplanken
|
||||
- Keine Änderung der ID-Strategie ohne umfassende Migration.
|
||||
- Bei neuen Entities standardisierte Felder aus `AbstractEntity` nutzen.
|
||||
- Collections initialisieren (z.B. `new ArrayList<>()`) im Entity-Konstruktor.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user