Files
pi_mcps/java/mss-failsafe/.github/manager_controller_pattern.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

103 lines
4.1 KiB
Markdown
Executable File

# 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.
---