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:
Executable
+64
@@ -0,0 +1,64 @@
|
||||
# AI Instruktionen für Code-Generierung
|
||||
|
||||
Ziel: Ein konsistenter Kontext für zukünftige automatische Ergänzungen.
|
||||
|
||||
## Projekt-Kurzprofil
|
||||
- Typ: Java EE 8 (javax), WAR, JSF + PrimeFaces, Hibernate JPA.
|
||||
- Java Version: 11 (Compiler Plugin).
|
||||
- Schichten: Model (Entities), Business (Manager), Controller (JSF Beans), View (XHTML).
|
||||
|
||||
## Wichtige Basisklassen
|
||||
- `AbstractEntity`: Basisklasse aller Entities (enthält ID – Details nicht gezeigt, aber zentral).
|
||||
- `AbstractManager<T>`: Generisches CRUD mit `save`, `saveAll`, etc.
|
||||
- `AbstractController<E>`: UI State & Utilities.
|
||||
|
||||
## Konventionen (Kurz)
|
||||
- Neue Entities: extend `AbstractEntity`, Named Queries definieren.
|
||||
- Neue Manager: `@Stateless`, extends `AbstractManager<Entity>`, implementiert `getEntityManager()`.
|
||||
- Neue Controller: `@Named`, Scope Annotation (`@ViewScoped` etc.), extends `AbstractController<Entity>`, implementiert `getManager()`.
|
||||
- Temporäre (nicht persistierte) Objekte: negative ID (Fake) bis finalem Speichern.
|
||||
|
||||
## CRUD Muster (Beispiel)
|
||||
```java
|
||||
@Stateless
|
||||
public class ExampleEntityManager extends AbstractManager<ExampleEntity> {
|
||||
@PersistenceContext(name = "pu_person") EntityManager em;
|
||||
public ExampleEntityManager(){ super(ExampleEntity.class); }
|
||||
@Override protected EntityManager getEntityManager(){ return em; }
|
||||
}
|
||||
```
|
||||
|
||||
## Typische Aufgaben für Generierung
|
||||
1. Neue Domain + Entity + Manager + Controller + XHTML.
|
||||
2. PDF-Ausgabe Erweiterung.
|
||||
3. Batch-Speichern mehrerer neuer Entities.
|
||||
4. Klon-Operationen: Copy-Konstruktor nutzen, Child-IDs auf `null` setzen, Referenzen neu knüpfen.
|
||||
5. Fragebogen-Workflow: add/remove (siehe `QUESTIONNAIRE_WORKFLOW.md`).
|
||||
|
||||
## Qualitätssicherung
|
||||
- Nach Code-Erzeugung: Prüfe Kompilierung (mvn -q test / package).
|
||||
- Sicherstellen: Keine direkten System.out Prints in Produktionscode.
|
||||
- Logging: `LOGGER.error(e)` bei Exceptions.
|
||||
|
||||
## Häufige Edge Cases
|
||||
- Null Checks vor Persist/Remove.
|
||||
- Negative ID Objekte dürfen nicht direkt gelöscht (erst persistieren oder aus Collection entfernen).
|
||||
- Lazy Collections müssen initialisiert vor Iteration (via `refresh` oder `Hibernate.initialize`).
|
||||
|
||||
## Verbesserungsvorschläge (safe additions)
|
||||
- Service Layer Einführen (wenn Logik Manager übersteigt).
|
||||
- Bean Validation (@NotNull, @Size) auf Entities.
|
||||
- Einheitliche Exception Klasse.
|
||||
|
||||
## Generierungs-Präferenzen
|
||||
- Bevorzugt vorhandene Muster exakt replizieren.
|
||||
- Keine neuen Frameworks ohne Bedarf.
|
||||
- Code kommentieren nur bei komplexer Logik.
|
||||
|
||||
## Anti-Pattern vermeiden
|
||||
- Business Logik direkt im Controller.
|
||||
- Duplizierte Query Strings ohne Named Query.
|
||||
|
||||
---
|
||||
Letzte Aktualisierung: 2025-10-20
|
||||
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
# Architekturübersicht
|
||||
|
||||
## Layer
|
||||
1. Präsentation: JSF 2.3 + PrimeFaces 11 (XHTML in `webapp/`).
|
||||
2. Controller Layer: JSF Managed Beans (CDI `@Named`, Scopes) – koordiniert UI → Business.
|
||||
3. Business Layer: Stateless EJB Manager (`business.*Manager`) – kapselt Datenzugriff + Fachlogik.
|
||||
4. Persistenz Layer: JPA (Javax) + Hibernate Provider. Persistence Context Name: `pu_person`.
|
||||
5. Ressourcen: `src/main/resources` für Log4j2, statische Texte, Checklisten.
|
||||
|
||||
## Zentrale Basisklassen
|
||||
### AbstractManager<T extends AbstractEntity>
|
||||
- Generisches CRUD: `save`, `saveAll`, `create`, `edit`, `remove`, `refresh`, `find`, `findAll`, `count`.
|
||||
- Flush nach Persist/Merge (stellt zeitnah DB-Konsistenz sicher).
|
||||
- Fehlerbehandlung: try/catch + Logging (Verbesserungspotential: Konsistente Exception).
|
||||
|
||||
### AbstractController<ENT extends AbstractEntity>
|
||||
- UI State: `selected`, `created`, `entities`.
|
||||
- Utility: Faces Messages, PDF Hilfsmethoden, Fake-ID Generator für neue Entities vor Persist.
|
||||
- `refrehSelected()`: Re-merge & initialize Lazy Collections.
|
||||
|
||||
## Entity Lebenszyklus (UI Sicht)
|
||||
1. Nutzer erstellt neues Objekt → Controller vergibt Fake-ID (negativ) mittels `createFakeID(Collection<ENT>)`.
|
||||
2. Objekt wird in Listen angezeigt, kann editiert werden bevor persistiert.
|
||||
3. Beim Speichern werden alle mit `id < 0` auf `null` gesetzt; `AbstractManager.saveAll()` persistiert.
|
||||
4. Nach Persist: DB generiert positive ID.
|
||||
|
||||
## Sicherheitsbereich (SecurityArea)
|
||||
- Enthält Listen: `SecurityDevices`, `DangerPoints`, `SwitchingDevices`, `Questionnaires`.
|
||||
- Manager-Methoden: `cloneArea`, add/remove Questionnaire, `reloadWithQuestionnaires`.
|
||||
- Klonen: Erst DB laden (falls persistent), dann Kopie via Copy-Konstruktor `new SecurityArea(area)`.
|
||||
|
||||
## Fragebogen-Zuordnung
|
||||
- Hinzufügen: `SecurityAreaManager.addQuestionnaireToSecurityArea` erzeugt `SecurityAreaQuestionnaire` Wrapper (assoziative Entity) & persistiert.
|
||||
- Entfernen: Entities werden aus Sammlung entfernt und via `em.remove(questionnaire)` gelöscht.
|
||||
- Verfügbare Fragebögen: Alle `Questionaire` minus bereits zugeordnete (Filter per Namen – potentielles Verbesserungspotential: Verwendung IDs statt Name).
|
||||
|
||||
## Transaktionen
|
||||
- Methoden mit Schreiboperationen annotiert `@Transactional` (EJB Container verwaltet JTA). In `AbstractManager` ebenfalls.
|
||||
|
||||
## Logging
|
||||
- Log4j2 überall via `LogManager.getLogger(...)`. Konfiguration: `log4j2.xml`.
|
||||
|
||||
## PDF Generierung
|
||||
- `AbstractController` Hilfsmethoden zur Tabellen-Erstellung (iText7) + gemischte Nutzung iText5 (itextpdf 5.5.13) – Migration empfohlen.
|
||||
|
||||
## Erweiterbarkeit
|
||||
- Neue Fachbereiche folgen Pattern: Entity → Manager → Controller → UI.
|
||||
- Reusable generische Methoden vermeiden Duplikate (Beispiel: `saveAll`, `refresh`).
|
||||
|
||||
## Bekannte technische Schulden
|
||||
- Mischung iText5 & iText7.
|
||||
- Fehlerbehandlung inkonsistent (bool Rückgaben + Logging).
|
||||
- Kein einheitlicher DTO Layer – Controller arbeitet direkt auf Entities (Risk: Lazy Loading im View).
|
||||
- Wenige Tests im `test/` Verzeichnis.
|
||||
|
||||
## Ideen für Refactoring
|
||||
- Einführung Service Layer (falls Business Logik komplexer wird) zw. Controller und Manager.
|
||||
- Exceptions mit Custom Runtime (`BusinessException`) statt stiller bool False.
|
||||
- Verwendung Criteria / NamedQueries für Wiederverwendbarkeit (z.Z. direkte Query Strings in Manager).
|
||||
|
||||
---
|
||||
Aktualisiert: 2025-10-20
|
||||
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
# Coding Guidelines
|
||||
|
||||
## Allgemein
|
||||
- Sprache: Deutsch in UI-Messages, Englisch im Code (Klassennamen etc.).
|
||||
- Einrückung: 4 Spaces (NetBeans Standard). Keine Tab-Mischung.
|
||||
- Zeilenlänge: Empfehlung max. 140 Zeichen.
|
||||
- Vermeide überflüssige System.out.println – nutze Logger.
|
||||
|
||||
## Packages
|
||||
- `business.<domain>` für Manager/Logik.
|
||||
- `controller.<domain>` für JSF Backing Beans.
|
||||
- `model.<domain>` für Entities/Enums.
|
||||
|
||||
## Benennung
|
||||
- Manager endet auf `Manager` (CRUD + Fachlogik).
|
||||
- Controller endet auf `Controller`.
|
||||
- Entities nutzen Substantive singular (`SecurityArea`, `DangerPoint`).
|
||||
- Enums nutzen PascalCase Konstanten (`APPROACH_SPEED`, hier bereits gemischt – beibehalten vorhandene Fälle, Konsistenz bei neuen).
|
||||
|
||||
## Fehlerbehandlung
|
||||
- Aktuell: Logging + bool Rückgabe. Bei neuen komplexen Methoden: Ziehe eigene Exceptions in Betracht (`BusinessException`).
|
||||
- Niemals stack trace verlieren – immer loggen. Falls Benutzerfeedback nötig → Message über Controller.
|
||||
|
||||
## Persistenz
|
||||
- Vor Persist neuer Entity: ID muss `null` sein (oder negativ Fake-ID nur temporär). Setze beim finalen Speichern negative IDs auf `null`.
|
||||
- Verwende `AbstractManager.refresh(entity)` um Lazy Collections zu initialisieren.
|
||||
|
||||
## Transaktionen
|
||||
- Schreibmethoden erhalten `@Transactional`. Beim EJB Stateless reicht oft Container-Transaktion; Annotation verstärkt Klarheit.
|
||||
|
||||
## Performance
|
||||
- Sammel-Speicheroperationen bevorzugt `saveAll(Collection<T>)` statt Schleifen mit einzelnen Flushes.
|
||||
- Beim Klonen großer Objektgraphen prüfen: Nur notwendige Collections initialisieren.
|
||||
|
||||
## UI / JSF
|
||||
- Vermeide direkte Änderungen an listengebundenen Collections ohne Aktualisierung des Backing Beans (PrimeFaces kann sonst nicht updaten).
|
||||
- Nutze klare Dialog-Helper (closeDialogs) statt roher JavaScript Strings.
|
||||
|
||||
## PDF
|
||||
- Konsistenz: Verwende iText7 API für neue Funktionen. Markiere Altcode (iText5) für spätere Entfernung.
|
||||
|
||||
## Sicherheit
|
||||
- Keine sensiblen Daten in Logs.
|
||||
- Prüfe vor Löschaktionen, dass referenzielle Integrität gewährleistet (vor Entfernen Beziehungen lösen, wie im `deleteSelected()` umgesetzt).
|
||||
|
||||
## Tests (Empfehlung)
|
||||
- JUnit + Arquillian für EJB/Entity Tests.
|
||||
- Test-Namensschema: `<ClassName>Test`.
|
||||
- Mindestens: CRUD, Klonen, Fragebogen hinzufügen/entfernen.
|
||||
|
||||
## Kommentar-Stil
|
||||
- Klassenheader: Kurze Beschreibung Funktion/Zweck.
|
||||
- Methoden: JavaDoc nur bei komplexer Logik / öffentlich verwendeten APIs.
|
||||
|
||||
## Anti-Pattern vermeiden
|
||||
- "God Controller" – trenne Verantwortlichkeiten (nicht alles in einem Controller ansammeln).
|
||||
- Direkte UI-Logik im Manager vermeiden.
|
||||
|
||||
---
|
||||
Aktualisiert: 2025-10-20
|
||||
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
# How-To: Projekt erweitern
|
||||
|
||||
## Neuer Fachbereich (Beispiel: InspectionReport)
|
||||
|
||||
### 1. Entity anlegen
|
||||
- Paket: `model.report`.
|
||||
- Klasse: `InspectionReport extends AbstractEntity`.
|
||||
- Felder: `date`, `inspector`, `machine`, `remarks`.
|
||||
- Named Queries definieren (z.B. `FIND_BY_MACHINE`).
|
||||
|
||||
### 2. Manager
|
||||
```java
|
||||
@Stateless
|
||||
@Named
|
||||
public class InspectionReportManager extends AbstractManager<InspectionReport> {
|
||||
@PersistenceContext(name = "pu_person")
|
||||
EntityManager em;
|
||||
public InspectionReportManager() { super(InspectionReport.class); }
|
||||
@Override protected EntityManager getEntityManager() { return em; }
|
||||
// Fachmethoden: findByMachine(Long id)
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Controller
|
||||
```java
|
||||
@ViewScoped
|
||||
@Named
|
||||
public class InspectionReportController extends AbstractController<InspectionReport> {
|
||||
@EJB InspectionReportManager reportManager;
|
||||
@Inject MachineController machineController;
|
||||
public InspectionReportController() { setSelected(new InspectionReport()); setCreated(new InspectionReport()); }
|
||||
@Override protected AbstractManager<InspectionReport> getManager() { return reportManager; }
|
||||
@Override public void clearEntries() { setSelected(new InspectionReport()); setCreated(new InspectionReport()); getEntities().clear(); }
|
||||
public void saveReport(){ reportManager.save(getSelected()); successMessage(); }
|
||||
}
|
||||
```
|
||||
|
||||
### 4. UI Seite
|
||||
- Pfad: `webapp/report/inspection.xhtml`.
|
||||
- Binding: `#{inspectionReportController}`.
|
||||
- Komponenten: Formular für Felder + Speichern Button.
|
||||
|
||||
### 5. Navigation
|
||||
- Menüeintrag in globaler Navigationsstruktur (Tree oder Topbar) – analog `createMachineMenu()` Ansatz.
|
||||
|
||||
### 6. Tests
|
||||
- Persistenz Test: Speichern + Laden.
|
||||
- Manager Fachmethode Test.
|
||||
|
||||
## Erweiterung vorhandener Funktionalität
|
||||
- Beispiel: Neue PDF Sektion → Ergänze Hilfsmethode in `AbstractController` (sofern allgemein). Falls spezifisch für eine Domäne, eher Hilfsklasse im Domain-Paket.
|
||||
|
||||
## Konsistenz-Checkliste
|
||||
- [ ] Entity extends `AbstractEntity`
|
||||
- [ ] Manager extends `AbstractManager`
|
||||
- [ ] Controller extends `AbstractController`
|
||||
- [ ] Negative IDs für neue Objekte vor Persist (falls in Listen)
|
||||
- [ ] Internationale Zeichen (UTF-8) – POM setzt Encoding
|
||||
- [ ] Logging bei Fehlern
|
||||
|
||||
## Deployment Hinweise
|
||||
- Sicherstellen, dass neue Named Queries beim Serverstart verfügbar (Entity korrekt gescannt).
|
||||
- Falls neue Ressourcen (Logos, Templates) → in `resources` pflegen.
|
||||
|
||||
## Typische Stolpersteine
|
||||
- LazyInitializationException: Lösung `refresh(entity)` oder explizite Initialisierung im Manager.
|
||||
- Doppelte Referenzen beim Klonen: IDs auf `null` setzen.
|
||||
- Fehlende Transaktion: Sicherstellen `@Transactional` oder EJB Standard.
|
||||
|
||||
---
|
||||
Aktualisiert: 2025-10-20
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
# Workflow: Fragebögen in Sicherheitsbereichen
|
||||
|
||||
## Ziel
|
||||
Zuordnung strukturiert erfassbarer Fragebögen (`Questionaire`) zu einem `SecurityArea` via `SecurityAreaQuestionnaire`.
|
||||
|
||||
## Beteiligte Klassen
|
||||
- `SecurityAreaController` – UI Aktionen (add/remove, refresh).
|
||||
- `SecurityAreaManager` – Persistenzoperationen (add/remove/reload, Verfügbarkeitsliste).
|
||||
- `SecurityAreaQuestionnaire` – Assoziative Entity (enthält Name / ID des Fragebogens + Bezug zum Schutzbereich).
|
||||
- `QuestionaireManager` (nicht gezeigt) – Verwaltung aller Fragebögen.
|
||||
|
||||
## Hinzufügen Ablauf
|
||||
1. Nutzer wählt Schutzbereich + Fragebogen im Dialog.
|
||||
2. Controller ruft `securityAreaManager.addQuestionnaireToSecurityArea(selectedArea, selectedQuestionnaire)`.
|
||||
3. Manager:
|
||||
- Lädt `area` (falls persistent) neu per `em.find`.
|
||||
- Erzeugt neues `SecurityAreaQuestionnaire` Objekt.
|
||||
- Setzt Relation (wrapper.setArea(area)).
|
||||
- Persistiert Wrapper, merged Area.
|
||||
4. Controller: `refrehSelected()` (Merge + Initialize Lazy Collections), zeigt Erfolgsmeldung.
|
||||
|
||||
## Entfernen Ablauf
|
||||
1. Nutzer wählt zugeordneten Fragebogen (Wrapper-Objekt).
|
||||
2. Controller ruft `securityAreaManager.removeQuestionnaireFromSecurityArea(area, wrapper)`.
|
||||
3. Manager lädt Entities (falls notwendig), entfernt aus Collection, `em.remove(wrapper)`, `em.merge(area)`.
|
||||
4. Controller aktualisiert Verfügbare Liste.
|
||||
|
||||
## Verfügbare Fragebögen
|
||||
- Abfrage aller Fragebögen: `SELECT q FROM Questionaire q ORDER BY q.name`.
|
||||
- Filter: Namen bereits zugeordneter Wrapper (Verbesserung: Filter per ID zur Sicherheit gegen Namensduplikate).
|
||||
|
||||
## Edge Cases
|
||||
- Bereich / Fragebogen null: Controller zeigt Fehlermeldung.
|
||||
- Concurrent Änderung: Nach Persist immer Refresh durchführen.
|
||||
- Doppelte Zuordnung: Filter verhindert erneute Anzeige; Manager könnte zusätzlich prüfen (Collection enthält bereits Name).
|
||||
|
||||
## Verbesserungen
|
||||
- Validierung auf Einzigartigkeit im Manager (statt nur UI Filter).
|
||||
- Optimierte Fetch Strategie (JOIN FETCH) bei Reload.
|
||||
- Nutzung eines Service zur Kapselung Geschäftslogik + Manager nur für CRUD.
|
||||
|
||||
## Beispiel Pseudocode (Hinzufügen)
|
||||
```java
|
||||
if (questionnaire != null && area != null) {
|
||||
areaManager.addQuestionnaireToSecurityArea(area, questionnaire);
|
||||
controller.refrehSelected();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
Aktualisiert: 2025-10-20
|
||||
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
# Mechanismus: Refresh & Fake-ID
|
||||
|
||||
## Problemstellung
|
||||
Im UI werden häufig neue Objekte in Collections angezeigt, bevor sie persistiert sind. Diese benötigen eine temporäre Identifikation (ID) für Auswahl/Operationen, ohne den Datenbankzustand zu verfälschen.
|
||||
|
||||
## Fake-ID Strategie
|
||||
- Negative Long Werte (< 0) kennzeichnen nicht persistierte Objekte.
|
||||
- Erzeugung: `AbstractController.createFakeID(Collection<ENT>)`:
|
||||
- Startwert -1.
|
||||
- Falls bereits negative IDs existieren → Nimmt die kleinste negative und subtrahiert 1.
|
||||
- Ergebnis: Sequenz -1, -2, -3 ... (absteigend).
|
||||
|
||||
## Persistieren
|
||||
Vor finalem Speichern (z.B. `SecurityAreaController.save()`):
|
||||
1. Alle Entities mit `id < 0` → `setId(null)`.
|
||||
2. `AbstractManager.saveAll()` unterscheidet durch `entity.getId() == null` zwischen Persist und Merge.
|
||||
3. Datenbank vergibt positive ID (Auto Increment / Sequence).
|
||||
|
||||
## Vorteile
|
||||
- Klare Unterscheidung UI-temporär vs. persistent.
|
||||
- Verhindert versehentliches Auslösen von Merge bei noch nicht existierenden DB Zeilen.
|
||||
|
||||
## Risiken
|
||||
- Verwechslung negativ gesetzter IDs mit echten IDs (nicht möglich, da DB positive IDs generiert).
|
||||
- Direkte Verwendung negativer IDs in DB-Operationen (vermeiden: Prüfen auf `id > 0` vor `em.find`).
|
||||
|
||||
## Refresh
|
||||
- Methode `AbstractController.refrehSelected()` (Tippfehler im Namen, historisch) ruft `getManager().refresh(selected)`.
|
||||
- `AbstractManager.refresh(entity)`:
|
||||
- Falls ID null → `save(entity)` (persistiert neues Objekt).
|
||||
- `merge` für Managed Zustand und `Hibernate.initialize(entity)` zur Lazy Init.
|
||||
|
||||
## Best Practices
|
||||
- Nach komplexen Änderungen (Add/Remove Child Collections) Refresh durchführen wenn UI weitere Lazy Properties benötigt.
|
||||
- Beim Klonen persistenter Objekte zuerst DB-Laden → danach Kopie erstellen.
|
||||
|
||||
## Potentielle Verbesserungen
|
||||
- Korrektur Tippfehler `refrehSelected()` → `refreshSelected()` (Refactoring + Suchanpassungen).
|
||||
- Kennzeichnung Fake-ID generierender Methoden mit JavaDoc für Klarheit.
|
||||
|
||||
---
|
||||
Aktualisiert: 2025-10-20
|
||||
# MSS Failsafe – Developer Einstieg
|
||||
|
||||
Dieses Verzeichnis bündelt technische Instruktionsdateien zur schnelleren Einarbeitung und zur Unterstützung automatischer Code-Generierung.
|
||||
|
||||
## Quick Start
|
||||
1. Java Version: Quell-/Ziellevel im POM: 11 (Property 1.8 ist historisch, der Compiler-Plugin setzt auf 11). Nutze lokal JDK 11.
|
||||
2. Application Server: Java EE 8 kompatibel (z.B. Payara 5 / WildFly 20 / GlassFish 5). Dependencies `javax.*` statt `jakarta.*`.
|
||||
3. Build:
|
||||
```cmd
|
||||
mvn clean package
|
||||
```
|
||||
Ergebnis: `target/mss-1.0-SNAPSHOT.war`.
|
||||
4. Deployment: WAR in kompatiblen EE 8 Server einspielen. Konfiguriere Datenquelle `pu_person` (JPA Persistence Unit – siehe `@PersistenceContext(name = "pu_person")`).
|
||||
5. Logging: Log4j2 Konfiguration in `src/main/resources/log4j2.xml`.
|
||||
6. Frontend: JSF 2.3 + PrimeFaces 11 + PrimeFlex 2.0.
|
||||
|
||||
## Wichtigste Schichten
|
||||
- model: JPA Entities (`AbstractEntity` Basis – enthält ID).
|
||||
- business: `*Manager` Klassen (Stateless EJBs) kapseln CRUD + Fachlogik.
|
||||
- controller: View/Request/Session Scoped JSF Backing Beans (Interaktion UI ↔ Business Layer).
|
||||
- webapp: XHTML Seiten (JSF Components + PrimeFaces).
|
||||
- resources: Text-/Konfigurationsdateien, Checklisten.
|
||||
|
||||
## Kern-Patterns
|
||||
- Manager erben von `AbstractManager<T>` (generisches CRUD mit `save`, `saveAll`, `remove`, `refresh`).
|
||||
- Controller erben von `AbstractController<E>` (Message Handling, Fake-ID-Erzeugung für neue (noch nicht persistierte) Entities, PDF Hilfen, Auswahlzustand `selected/created`).
|
||||
- Negative IDs (< 0) werden als temporäre (noch nicht persistierte) Objekte verwendet – wichtig bei UI-Listen vor Sammel-Speichern.
|
||||
- Lazy Collections werden vor Nutzung mit `Hibernate.initialize(...)` initialisiert (Refresh/Reload Methoden).
|
||||
|
||||
## Erweiterung – Schnellanleitung
|
||||
1. Neue Entity anlegen (JPA @Entity, extends `AbstractEntity`).
|
||||
2. Manager erstellen: `@Stateless`, extends `AbstractManager<YourEntity>`, implementiert `getEntityManager()`. Zusätzliche Named Queries in Entity definieren.
|
||||
3. Controller erstellen: `@Named`, Scope festlegen (`@ViewScoped`, `@SessionScoped`, etc.), extends `AbstractController<YourEntity>`, injiziere Manager mit `@EJB`.
|
||||
4. XHTML Seite/Fragment erstellen und Controller referenzieren (`#{yourController}`) + PrimeFaces Komponenten.
|
||||
5. Tests (optional, derzeit kaum vorhanden) – vorschlagen: Architektur-Test + Manager CRUD Test.
|
||||
|
||||
## Fragebögen / Sicherheitsbereiche
|
||||
Ein ausführlicher Workflow liegt in `QUESTIONNAIRE_WORKFLOW.md` und `SECURITY_AREA_DOMAIN.md`.
|
||||
|
||||
## PDF-Erzeugung
|
||||
- Verwendet iText (5.x + 7.x Module). Utilities liegen in `AbstractController` (Tabellen, Kopfzeilen, Seitennummern).
|
||||
- Logo Pfad `LOGO_PATH = /rundata/logo.png` – stelle sicher, dass Datei beim Deployment verfügbar ist.
|
||||
|
||||
## Automatisierte Tools / AI Hinweise
|
||||
Siehe `AI_INSTRUCTIONS.md` für formatierte Kontextbereitstellung.
|
||||
|
||||
## Nächste Verbesserungen (Empfehlungen)
|
||||
- Konsolidierung auf iText7 (Legacy 5.x entfernen).
|
||||
- Einheitliche Exception-Strategie (momentan Logging + bool Rückgabe).
|
||||
- Mehr Unit Tests (Persistenz, Controller Interaktionen via Arquillian / Payara Micro).
|
||||
- Migrationspfad Richtung Jakarta EE 9+ (Namespace Wechsel).
|
||||
|
||||
---
|
||||
Letzte Aktualisierung: 2025-10-20
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
# Domain: SecurityArea
|
||||
|
||||
## Zweck
|
||||
Abbildung eines Schutzbereichs einer Maschine mit zugehörigen Schutzeinrichtungen, Gefahrenstellen und Schaltgeräten sowie Fragebögen zur Bewertung.
|
||||
|
||||
## Haupt-Entitäten (Ausschnitt)
|
||||
- `SecurityArea`
|
||||
- `SecurityDevice` (Liste in Area)
|
||||
- `DangerPoint`
|
||||
- `SwitchingDevice`
|
||||
- `SecurityAreaQuestionnaire` (assoziative Entity zwischen Schutzbereich und `Questionaire`)
|
||||
- `Questionaire`
|
||||
|
||||
## Lebenszyklus
|
||||
1. Erstellung im UI: Neues `SecurityArea` Objekt mit Fake-ID (negativ).
|
||||
2. Bearbeitung von Eigenschaften (Name, Typen/Enums: `ProtectionType`, `MountingPosition`, `OverrunMeasurementType`, `ApproachSpeed`).
|
||||
3. Hinzufügen von Schutzeinrichtungen/Gefahrenstellen/Schaltgeräten (ebenfalls ggf. mit Fake-ID bis persistiert).
|
||||
4. Speichern: Negative IDs der neuen Objekte werden auf `null` gesetzt → Persist durch `SecurityAreaManager.save` / Sammelspeicher.
|
||||
5. Nach Persist: Re-Load (`refresh`/`reloadWithQuestionnaires`) vor weiterer Bearbeitung.
|
||||
|
||||
## Klonen
|
||||
`SecurityAreaManager.cloneArea(SecurityArea area)`:
|
||||
- Lädt persistente Quelle (falls ID > 0) vollständig.
|
||||
- Erzeugt neue Kopie via Copy-Konstruktor.
|
||||
- Controller passt Namen an (`Original (Kopie)`), setzt neue `null` IDs für untergeordnete Objekte.
|
||||
|
||||
## Fragebogen-Verknüpfung
|
||||
### Hinzufügen
|
||||
- Methode: `addQuestionnaireToSecurityArea(area, questionnaire)`.
|
||||
- Erzeugt `SecurityAreaQuestionnaire` Wrapper.
|
||||
- Persist Wrapper, merge Area.
|
||||
- UI aktualisiert Liste und sendet Erfolgsmeldung.
|
||||
|
||||
### Entfernen
|
||||
- `removeQuestionnaireFromSecurityArea(area, securityAreaQuestionnaire)` entfernt Element aus Sammlung & ruft `em.remove`.
|
||||
|
||||
### Verfügbare Fragebögen
|
||||
- `getAvailableQuestionnaires(area)` holt alle `Questionaire` und filtert bereits zugeordnete anhand Name. Verbesserung: Nutzung ID statt Name zur Eindeutigkeit.
|
||||
|
||||
## Konsistenz / Referentielle Integrität
|
||||
Beim Löschen eines Schutzbereichs (`deleteSelected()` im Controller):
|
||||
1. Entfernen aus Maschine.
|
||||
2. Auflösen aller Kind-Referenzen (SwitchingDevices, DangerPoints, SecurityDevices) durch Setzen der Area auf `null`.
|
||||
3. Entfernen der Kindobjekte via entsprechende Manager (`removeAllIn`).
|
||||
4. Löschen des `SecurityArea` via Named Query (`SecurityArea.DELETE`).
|
||||
|
||||
## Potentielle Verbesserungen
|
||||
- Cascade Settings genauer prüfen (evtl. kann Teil der manuellen Löschlogik automatisiert werden).
|
||||
- Validierung (Bean Validation) für Pflichtfelder (Name nicht leer, Enums nicht null soweit fachlich notwendig).
|
||||
- Nutzung DTOs zur Entkopplung UI ↔ JPA (reduziert Lazy Probleme).
|
||||
|
||||
---
|
||||
Aktualisiert: 2025-10-20
|
||||
|
||||
Reference in New Issue
Block a user