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:
Patrick Plate
2026-06-13 19:55:28 +02:00
parent 7a573d7193
commit 1a0a56a626
504 changed files with 37052 additions and 7758 deletions
+84
View File
@@ -0,0 +1,84 @@
# AI Context Instructions
## Essentials
- Base Classes: AbstractEntity, AbstractManager<T>, AbstractController<E>
- Fake ID Mechanismus für neue Objekte
- Hibernate.initialize für Lazy Collections
# Architecture Instructions
## Typical Generation Tasks
1. Neue Domain (Entity/Manager/Controller/XHTML)
2. PDF Utility Erweiterung (iText7)
3. Sammel-Speichern (saveAll) bereitstellen
4. Klon-Operationen (IDs null setzen, Collections duplizieren kontrolliert)
5. Fragebogen Zuordnung (add/remove, available list)
## Edge Cases
- Null Entities im save -> return false
- Negative IDs beim remove -> zuerst persistieren oder aus UI entfernen
- Concurrency Refresh: Nach batch Änderungen refreshSelected()
## Do / Don't
- DO: Logging bei jeder Exception
- DO: Konsistente Nutzung von @Transactional bei Schreiboperationen
- DON'T: System.out oder ungefangene Exceptions durchreichen ohne Logging
- DON'T: Business Logik direkt in XHTML Event Handler schreiben
## Upgrade Ideas
- Exception Layer
- Bean Validation
- Service Layer zwischen Controller und Manager falls Logik wächst
---
Aktualisiert: 2025-10-20
## Purpose
Verdichtete Architekturhinweise für automatische Code-Generierung und schnelle Orientierung.
## Stack
- Java EE 8 (javax), WAR
- JSF 2.3 + PrimeFaces 11 + PrimeFlex 2.0
- Hibernate JPA (Persistence Unit: pu_person)
- Log4j2
## Layer
1. View (XHTML)
2. Controller (JSF/CDI Beans, extends AbstractController<E>)
3. Business (Stateless EJB Manager, extends AbstractManager<T>)
4. Persistence (JPA Entities, extends AbstractEntity)
## Base Classes
- AbstractManager<T>: CRUD (save, saveAll, refresh, remove), flush nach Persist/Merge.
- AbstractController<E>: UI State (selected, created, entities), Messages, PDF Utilities, Fake-ID-Erzeugung.
## Entity Lifecycle UI
- Neue Objekte: erhalten negative Fake-ID
- Vor Persist: negative IDs -> null setzen
- save/saveAll entscheidet anhand id == null zwischen persist/merge
## Lazy Loading
- Refresh via AbstractManager.refresh(entity) + Hibernate.initialize(entity)
- Für Collections: dedizierte reload Methoden (z.B. SecurityAreaManager.reloadWithQuestionnaires)
## PDF
- iText7 bevorzugt; Altbestand iText5 (itextpdf 5.5.13) kann später entfernt werden.
## Logging & Fehler
- LOGGER.error(e) bei Fehlern
- Aktuell viele bool Rückgaben; Verbesserungspotential: BusinessException
## Erweiterung Pattern
Entity -> Manager -> Controller -> XHTML
## Schulden / Verbesserungen
- Mischung iText5/7
- Inkonsistente Fehlerbehandlung
- Kein DTO Layer
- Wenige Tests
## Empfehlungen für Generator
- Bestehende Signaturen unverändert lassen
- @Transactional nur bei Schreibmethoden hinzufügen
- Collections initialisieren bevor darauf iteriert wird
---
Aktualisiert: 2025-10-20
+75
View File
@@ -0,0 +1,75 @@
# 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.
---
+43
View File
@@ -0,0 +1,43 @@
# Cloning Instructions
Aktualisiert: 2025-10-20
## Ziel
Sicheres Klonen von komplexen Domains (z.B. SecurityArea inkl. Sub-Entities) ohne ID-Kollisionen oder versehentliches Persistieren historischer Referenzen.
## Grundprinzipien
- Nur persistente Quelle klonen (ID > 0) -> Vorher `refresh` zur Initialisierung Lazy Collections.
- Neue Instanzen erhalten `id = null` (oder negative Fake-ID falls im UI direkt angezeigt).
- Child-Entitäten ebenfalls mit `id = null` erzeugen.
## Vorgehen (Muster)
1. Quelle laden (Manager.find) & `refresh`.
2. Copy-Konstruktor oder Factory-Methode: Primitive Felder kopieren, Collections iterieren.
3. Collections: Neue Collection erzeugen, für jedes Kind tiefes Copy erstellen (kein Reuse Managed Instanz!).
4. IDs aller Kinder null setzen.
5. Optionale Anpassungen (Name -> "Kopie von <original>").
6. Rückgabe unverpersistiertes Root-Objekt an Controller.
## Tiefe vs. Flache Kopie
- Tiefe Kopie: Notwendig wenn Kinder eigenständige persistente Entities sind.
- Flache Kopie: Ausreichend falls nur Referenzen (Read-Only) erhalten bleiben sollen; aktuell bevorzugt tiefe Kopie für isolierte Bearbeitung.
## Edge Cases
- Quelle == null -> abort.
- Quelle mit Lazy Collections nicht initialisiert -> Gefahr LazyInitializationException.
- Zyklische Referenzen -> sorgfältig verhindern Endlosschleifen (ggf. bereits geklonte Instanzen in Map tracken).
## Fake IDs
- Wenn Klon direkt in UI Collection erscheint: negative ID via `createFakeID` generieren.
- Vor persist -> ID auf null setzen.
## Verbesserungen
- Einführung eines generischen `CloneService` mit rekursiver Strategie und Zyklus-Erkennung.
- Annotation @SkipClone für Felder die nicht übernommen werden sollen.
## Generator Leitplanken
- Keine Reflection-Magie für tiefe Kopien; lieber explizite Copy-Konstruktoren für Lesbarkeit.
- Reihenfolge: zuerst Root, dann Kinder.
---
+43
View File
@@ -0,0 +1,43 @@
# Coding Guidelines Instructions
## Naming
- Manager: *Manager
- Controller: *Controller
- Entities: Singular Substantive
- Negative IDs: temporäre Objekte
## Style
- 4 Spaces
- Logger statt System.out
- Deutsche UI-Texte, Englisch im Code
## Error Handling
- Log + Rückgabe (bestehend); für neue komplexe Logik optional BusinessException
## Persistenz
- Neue Entity: id == null vor persist
- refresh(entity) nutzen um Lazy Collections zu initialisieren
## Transaktionen
- Schreibmethoden: @Transactional (oder rely auf EJB Container)
## Performance
- Sammeloperationen: saveAll(Collection<T>)
## UI
- PrimeFaces Dialoge schließen mit closeDialogs
- Negative IDs in Listen bis Sammelspeichern
## PDF
- Neue Funktionen nur mit iText7 API
## Tests (Empfehlung)
- CRUD Manager Tests
- Klon & Fragebogen Zuordnung
## Anti-Pattern
- Logik nicht direkt im Controller wenn generell wiederverwendbar
- Keine duplizierten Query Strings -> Named Queries
---
Aktualisiert: 2025-10-20
+46
View File
@@ -0,0 +1,46 @@
# Error Handling Instructions
Aktualisiert: 2025-10-20
## Aktueller Zustand
- Fehler werden in Managern primär über `LOGGER.error(e)` geloggt.
- Rückgabe bool (true/false) signalisiert Erfolg/Misserfolg.
- Keine differenzierte Fehlerklassifikation (Business vs. System).
## Ziele
- Konsistente Behandlung & klare Trennung der Fehlerarten.
- Verbesserte Diagnose für Nutzer & Logs.
## Kategorien
1. Validation Errors (Bean Validation zukünftig) -> Nutzerfeedback.
2. Business Rule Violations -> eigene Exception (z.B. `BusinessException`).
3. System Errors (DB Down, Hibernate Exceptions) -> Logging + generische Fehlermeldung.
## Kurzfristige Empfehlungen
- Bei allen catch-Blöcken: `LOGGER.error("<Kontext>", e)` statt nur `LOGGER.error(e)`.
- Controller: Nach boolean false -> `errorMessage()` anzeigen.
## Einführung BusinessException (geplant)
- Checked oder Runtime? Vorschlag: Runtime zur vereinfachten Nutzung.
- Manager Methoden können `throw new BusinessException("Message")` statt false.
- Controller fängt BusinessException und zeigt spezifische Nachricht.
## Log Format
- Kontext + Entity-ID + Operation.
Beispiel: `LOGGER.error("Failed to persist SecurityArea id={} name={}", area.getId(), area.getName(), e);`
## Edge Cases
- Null Übergaben -> früh validieren & BusinessException werfen (später) / false zurückgeben (jetzt).
- Sammeloperation: Teilfehler -> aktuell Abort bei erstem Fehler. Optional Sammeln & Aggregatfehler.
## Verbesserungen
- Central Exception Mapper (JSF PhaseListener / CDI Interceptor).
- Korrelation IDs in Logs (Request ID, User ID).
## Generator Leitplanken
- Logging immer, auch bei ignorable Exceptions.
- Keine System.out Nutzung.
- Fehler nicht stillschweigend verschlucken (mindestens loggen).
---
+33
View File
@@ -0,0 +1,33 @@
# Extend Project Instructions
## Pattern
Entity -> Manager -> Controller -> XHTML -> Navigation
## Steps (Template)
1. Entity: @Entity extends AbstractEntity
2. Manager: @Stateless extends AbstractManager<Entity>
3. Controller: @Named + Scope extends AbstractController<Entity>
4. UI: xhtml mit #{controller}
5. Tests: CRUD + Spezialmethoden
## Fake IDs
- Neue Objekte in Collections: negative ID (createFakeID)
- Vor Persist: setId(null)
## Klonen
- Quelle laden & initialisieren
- Copy-Konstruktor
- Child IDs null
## Checklist
- [ ] Named Queries falls benötigt
- [ ] Logging bei Fehlern
- [ ] @Transactional bei Schreibmethoden
- [ ] Keine System.out
## Common Pitfalls
- LazyInitializationException -> refresh
- Vergessen negative IDs zurückzusetzen -> Persist fehlschlägt
---
Aktualisiert: 2025-10-20
+31
View File
@@ -0,0 +1,31 @@
# General Project Instructions
## Quick Facts
- Java EE 8 (javax) / Java 11 / WAR
- JSF + PrimeFaces + PrimeFlex
- Persistence Unit: pu_person
- Logging: Log4j2
## Build
mvn clean package -> target/mss-1.0-SNAPSHOT.war
## Core Patterns
- Manager: CRUD + Fachmethoden (extends AbstractManager)
- Controller: UI State + Messages + PDF (extends AbstractController)
- Negative IDs für temporäre Objekte
## PDF
- iText7 bevorzugen; Legacy iText5 entfernen später
## Improvements Roadmap
- Vereinheitlichte Exception Strategie
- Test Suite aufbauen
- Migration nach Jakarta EE (Namespace Wechsel)
## AI Generation Hints
- Halte Signaturen stabil
- Keine neuen Frameworks
- Initialisiere Lazy Collections vor Nutzung
---
Aktualisiert: 2025-10-20
+53
View File
@@ -0,0 +1,53 @@
# Index Instructions
Aktualisiert: 2025-10-20
Zentraler Überblick über alle *.instructions.md Dateien im Ordner `.github` für automatische Nutzung.
## Übersicht Bestehend
- Architektur: `architecture.instructions.md`
- Coding Guidelines: `coding_guidelines.instructions.md`
- Domain (Security Area): `security_area_domain.instructions.md`
- Fragebogen Workflow: `questionnaire_workflow.instructions.md`
- Projekt Erweiterung: `extend_project.instructions.md`
- Refresh & Fake-ID Mechanismus: `refresh_fake_id.instructions.md`
- Allgemeine Projektinfo: `general_project.instructions.md`
- AI Kontext / Generatorhinweise: `ai_context.instructions.md`
## Neue Spezial-Themen
- Persistence Layer: `persistence.instructions.md`
- PDF Generierung (iText7): `pdf_generation.instructions.md`
- Klon-Strategien: `cloning.instructions.md`
- Fehler & Logging: `error_handling.instructions.md`
- Test-Strategie: `testing_strategy.instructions.md`
- Transaktionen: `transactions.instructions.md`
- Manager/Controller Muster: `manager_controller_pattern.instructions.md`
## Verwendung (Automatisierung)
1. Start: `general_project.instructions.md` + `architecture.instructions.md` lesen.
2. Bei neuen Entities: `extend_project.instructions.md` + `persistence.instructions.md`.
3. Bei UI/Business Verkettung: `manager_controller_pattern.instructions.md`.
4. Für Fragebogenfunktionen: `questionnaire_workflow.instructions.md` + `security_area_domain.instructions.md`.
5. Für temporäre IDs & Refresh: `refresh_fake_id.instructions.md`.
6. Für PDF Features: `pdf_generation.instructions.md`.
7. Für Klon-Operationen: `cloning.instructions.md`.
8. Für Fehlerstrategie: `error_handling.instructions.md`.
9. Für Transaktionsregeln: `transactions.instructions.md`.
10. Für Qualitätsstil: `coding_guidelines.instructions.md`.
## Priorität bei Unklarheiten
1. `general_project.instructions.md`
2. `architecture.instructions.md`
3. `coding_guidelines.instructions.md`
4. Spezialthema betreffende Datei
## Pflegehinweise
- Beim Ändern von Basisklassen (AbstractManager / AbstractController / AbstractEntity) entsprechende Dateien aktualisieren.
- Tippfehler Methode `refrehSelected()` bei Umbenennung in Code auch in `refresh_fake_id.instructions.md` und `architecture.instructions.md` anpassen.
- Neue fachliche Domains erhalten eigene `<domain>.instructions.md` Datei mit Operations-, Entity- und Edge Case Liste.
## Roadmap Dokumentation
- Nach Einführung eines Exception Layers: `error_handling.instructions.md` erweitern.
- Nach Migration zu Jakarta: Alle Dateien Namespace Hinweis aktualisieren.
---
+102
View File
@@ -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.
---
+46
View File
@@ -0,0 +1,46 @@
# PDF Generation Instructions
Aktualisiert: 2025-10-20
## Kontext
PDF-Erstellung erfolgt aktuell über Hilfsmethoden in `AbstractController` mittels iText7.
## Kern-Hilfsmethoden
- `loadCompanyLogo()` -> Lädt Logo aus LOGO_PATH.
- `generateSorroundingTable(String header, float maxWidth)` -> Einspaltige Rahmen-Tabelle mit Header.
- `generateInnerTable(Text header, boolean last, String... values)` -> 2-Spalten Tabelle mit alternierender Hintergrundfarbe.
- `generateInnerTable(Text header, int nrColumns, boolean last, String... values)` -> Generisch n-Spalten Tabelle.
- `addInnerCells(Table table, String name, String value, boolean isGray)` / Overload -> Fügt Datenzeilen hinzu.
- `addPagenumbers(Document document, String ticketNr, Image nextPagesCompanyLogo)` -> Fügt Seitenzahlen & Logo hinzu.
## Gestaltungsrichtlinien
- Fonts: Standard Helvetica / Bold (Konstanten `FONT_NORMAL`, `FONT_BOLD`).
- Schriftgrößen klein (8F Inhalte, 11F Header, 12F Hauptheader) für konsistente Layouts.
- Wechselnde Hintergrundfarbe (LIGHT_GRAY) zur besseren Lesbarkeit.
## Erweiterung
Neue Tabellen-/Layout-Funktionen:
1. Prüfen ob existierende Methoden erweiterbar statt neue Variante.
2. Konsistenz in Font & Spaltenbreiten wahren.
3. Kein Hardcode von absoluten Positionen außer bei Kopf-/Fußzeilen.
## Ressourcen Pfade
- LOGO_PATH statisch: `/rundata/logo.png`. Anpassungen zentral vornehmen.
## Fehlerhandhabung
- Aktuell wenige try/catch Blöcke; bei Erweiterung: Fehler loggen (`LOGGER.error(e)`) und Benutzer über Controller Messages informieren.
## Edge Cases
- Leere Werte -> `-/-` Platzhalter.
- Null Tabelleninstanz in addInnerCells -> early return.
## Verbesserungen
- Einführung eines PDFUtility Service zur Entkopplung vom Controller.
- Parameterobjekt für dynamische Tabellenkonfiguration (Spaltenbreiten, Farben, Größen).
## Generator Leitplanken
- iText7 API weiterverwenden; keine neuen PDF Libraries.
- Wiederverwendbare Logik nicht direkt im konkreten Controller implementieren -> Utility / Service.
---
View File
+28
View File
@@ -0,0 +1,28 @@
# Questionnaire Workflow Instructions
## Add
areaManager.addQuestionnaireToSecurityArea(area, questionnaire)
- area ggf. re-laden
- Wrapper erzeugen
- Persist wrapper + merge area
- Rückgabe: aktualisierte Area
## Remove
areaManager.removeQuestionnaireFromSecurityArea(area, wrapper)
- area & wrapper re-laden
- Collection remove, em.remove(wrapper), em.merge(area)
## Available List
getAvailableQuestionnaires(area): SELECT q FROM Questionaire q ORDER BY q.name
- Filter: bereits zugeordnete Namen
## Edge Cases
- Null area/questionnaire -> Fehlermeldung
- Race condition -> nach Add/Remove refreshSelected()
## Verbesserungen
- ID statt Name für Filter
- Duplikatprüfung direkt im Manager
---
Aktualisiert: 2025-10-20
+25
View File
@@ -0,0 +1,25 @@
# Refresh & Fake ID Instructions
## Fake ID
- Negative Long Werte (<0) = temporär
- Sequenz: -1, -2, -3 ... (kleinste negative - 1)
- Erzeugung: AbstractController.createFakeID(Collection<E>)
## Persist
- Vor Speichern: if id < 0 -> setId(null)
- save/saveAll: id == null => persist, sonst merge
## Refresh
- AbstractController.refrehSelected() (Tippfehler) -> getManager().refresh(selected)
- AbstractManager.refresh(entity): if id == null -> save(entity); merge + Hibernate.initialize(entity)
## Best Practices
- Nach Add/Remove Child Collections refresh
- Beim Klonen zuerst Quelle laden
## Verbesserungen
- Methode umbenennen zu refreshSelected()
- JavaDoc für createFakeID
---
Aktualisiert: 2025-10-20
+39
View File
@@ -0,0 +1,39 @@
# Security Area Domain Instructions
## Entities
- SecurityArea
- SecurityDevice / DangerPoint / SwitchingDevice
- SecurityAreaQuestionnaire (Wrapper) + Questionaire
## Operations
- cloneArea(SecurityArea)
- addQuestionnaireToSecurityArea(area, questionnaire)
- removeQuestionnaireFromSecurityArea(area, wrapper)
- getAvailableQuestionnaires(area)
- reloadWithQuestionnaires(area)
## Workflow (Add Questionnaire)
1. Area laden (falls id > 0)
2. Wrapper erstellen & area setzen
3. Persist Wrapper, merge Area
4. Refresh im Controller
## Deletion Pattern
- Beziehungen lösen (Kinder area = null setzen)
- Kinder entfernen (Manager.removeAllIn)
- Area per Named Query löschen
## Edge Cases
- Duplicate questionnaire by name -> aktuell Filter per Name
- Verbesserung: Filter per ID
## Klonen
- Persistente Quelle re-laden, initialisieren
- Copy-Konstruktor & alle Child IDs auf null
## Verbesserungen
- CascadeSettings prüfen
- Bean Validation einsetzen
---
Aktualisiert: 2025-10-20
+49
View File
@@ -0,0 +1,49 @@
# Testing Strategy Instructions
Aktualisiert: 2025-10-20
## Ziele
Testabdeckung für kritische Pfade: CRUD, Clone, Fragebogen Zuordnung, Fake-ID Mechanismus.
## Testarten
1. Unit Tests (reine Logik, z.B. createFakeID, Klon Copy-Konstruktoren).
2. Integration Tests (Persistence + Manager Methoden gegen Test-DB). Möglich mit in-memory H2 + angepasster persistence.xml.
3. UI/Controller Smoke Tests (Optional, z.B. mit Selenium/Arquillian Graphene).
## Prioritäten
- AbstractManager.save / saveAll Edge Cases.
- remove / removeAllIn (Null, nicht persistierte Entities).
- createFakeID Sequenz (-1, -2, -3 ...).
- Fragebogen Add/Remove Workflow (Wrapper Persistenz, Filterliste).
- Klonen tiefer Objektgraph.
## Beispiel Unit Test Fälle
- createFakeID(null) => -1.
- createFakeID(leere Liste) => -1.
- createFakeID([id=-1]) => -2.
- createFakeID([id=-3, id=-1]) => -4.
## Integration Tests (CRUD)
- Persist neue Entity -> ID != null.
- Merge vorhandene Entity -> unverändert Fachfelder korrekt übernommen.
- saveAll mit gemischten (neue + vorhandene) -> alle persistent.
## Fehlerpfade
- save(null) -> false.
- remove(null) -> false.
- remove(entity ohne ID) -> false.
## Klon Tests
- Quelle & Klon dürfen nicht gleiche ID haben.
- Child Collections tief kopiert (Referenzen ungleich, Werte gleich).
## Tooling Vorschlag
- JUnit 5, Mockito für isolierte Tests von Controller-Hilfsmethoden.
- Testcontainers (Optional später) für realistischere DB.
## Generator Leitplanken
- Für neue Fachlogik minimal 1-2 Unit Tests + 1 Integration Test.
- Keine Abhängigkeit auf Produktionspfade in Unit Tests; Test-spezifische Testdaten-Builder.
---
+40
View File
@@ -0,0 +1,40 @@
# Transactions Instructions
Aktualisiert: 2025-10-20
## Kontext
Container-Managed Transaktionen (Java EE). Verwendung von `@Transactional` auf Manager-Methoden für Schreiboperationen.
## Grundsätze
- Jede persistierende Operation (create, edit, remove) innerhalb einer Transaktion.
- `save` und `saveAll` bereits mit `@Transactional` versehen.
- Leseoperationen können ohne Annotation auskommen (Default: kein Write-Lock nötig).
## Batch Operationen
- `saveAll(Collection<T>)`: Ein Transaktionskontext für gesamte Collection -> entweder komplett erfolgreich oder Abbruch beim Fehler.
- Optimierungspotential: Fehler sammeln, nicht sofort abbrechen.
## Refresh
- `refresh(entity)` führt merge aus; wenn `id == null` vorher persist -> bleibt innerhalb Transaktion falls aufgerufen durch `save`/`saveAll`.
## Remove
- `remove(entity)` ohne `@Transactional` in Basisklasse -> Empfehlung: Annotation hinzufügen in konkretem Manager wenn Delete-Fachlogik erweitert wird.
## Edge Cases
- Verschachtelte Aufrufe (save -> intern create/edit): Container handhabt Propagation (`REQUIRED`).
- LazyInitializationException vermeiden: innerhalb Transaktion initialisieren.
## Empfohlene Annotationen
- Zusätzliche fachliche Write-Methoden stets mit `@Transactional` versehen.
- Pure Read: Performancekritisch -> ggf. explizit `@Transactional(Transactional.TxType.SUPPORTS)` oder weglassen.
## Fehlerfall Verhalten
- Ungefangene RuntimeException -> Rollback durch Container.
- Aktuell Exceptions geloggt & boolean false -> verhindert Rollback. Verbesserung: BusinessException throw + Rollback.
## Generator Leitplanken
- Keine eigenen manuell geöffneten Transaktionen (kein `UserTransaction`).
- Konsistenz: Schreibmethoden annotieren, Leseoperationen nur bei Bedarf.
---