2 Commits

Author SHA1 Message Date
b8f8cc4150 Merge branch 'main' of https://git.kocoder.xyz/Diplomarbeit-Absolventenverein/pm
Some checks failed
Word Count / count-words (push) Failing after 29s
2026-03-20 22:11:18 +01:00
c2336f166a Abbildungtexte geändert 2026-03-20 22:11:14 +01:00

View File

@@ -578,11 +578,11 @@ public class EngineerApplication : ModelBase
}
```
Die Klasse erbt von `ModelBase`, wodurch automatisch die Audit-Felder `CreatedBy`, `CreatedOn`, `ModifiedBy` und `ModifiedOn` zur Verfügung stehen. Das Feld `Status` bildet den aktuellen Workflow-Schritt ab und kann die Werte „Draft", „Submitted", „Approved" oder „Rejected" annehmen. Die hochgeladene PDF-Datei wird nicht direkt gespeichert, sondern über eine `FileId` im Oqtane-Dateisystem referenziert.
Die Klasse erbt von `ModelBase`, wodurch automatisch die Audit-Felder `CreatedBy`, `CreatedOn`, `ModifiedBy` und `ModifiedOn` zur Verfügung stehen. Das Feld `Status` bildet den aktuellen Workflow-Schritt ab und kann die Werte „Draft", „Submitted", „Approved" oder „Rejected" annehmen. Die hochgeladene PDF-Datei wird nicht direkt gespeichert, sondern über eine `FileId` im Oqtane-Dateisystem referenziert. Das nachfolgende Klassendiagramm veranschaulicht diese Struktur und zeigt, wie Basis-Metadaten durch die Vorfahrenklasse abgedeckt werden, während antragsbezogene Daten in der Hauptklasse gekapselt bleiben.
```mermaid
%%| filename: classdiagram-engineer-application
%%| fig-cap: Klassendiagramm der EngineerApplication-Entität. Es veranschaulicht die Struktur und Vererbung von ModelBase. Grundlegende Metadaten werden durch die Basisklasse abgedeckt, während die spezifischen Antragsdaten, wie etwa Status und FileId, in der Hauptklasse gekapselt sind.
%%| fig-cap: Klassendiagramm der EngineerApplication-Entität
classDiagram
class EngineerApplication {
+int ApplicationId
@@ -608,9 +608,9 @@ classDiagram
Der Lebenszyklus eines Antrags durchläuft mehrere Phasen. Der Benutzer beginnt auf der Antragsseite `Apply.razor`, wo ein Formular mit Feldern für Titel, Kurzbeschreibung und einer Dateiauswahl über den integrierten Oqtane FileManager bereitgestellt wird. Der FileManager stellt eine benutzerfreundliche Upload-Oberfläche mit Fortschrittsanzeige bereit und akzeptiert ausschließlich PDF-Dateien. Die hochgeladene Datei wird dabei im Oqtane-Dateisystem abgelegt und das Modul speichert lediglich die resultierende Datei-ID in der Antragstabelle.
Beim Absenden des Formulars erstellt die clientseitige Methode `SubmitApplication` ein neues `EngineerApplication`-Objekt und befüllt es mit den Formulardaten. Der Status wird dabei automatisch auf „Published" gesetzt, zusammen mit den Zeitstempeln für Einreichung und Genehmigung. Die Methode unterscheidet anhand der `ApplicationId`, ob ein neuer Antrag über den Service `AddApplicationAsync` erstellt oder ein bestehender über `UpdateApplicationAsync` aktualisiert werden soll. Falls keine Datei ausgewählt wurde, wird der Vorgang mit einer entsprechenden Fehlermeldung abgebrochen. Die Kommunikation mit dem Server erfolgt über den injizierten `ApplicationService`, der als HTTP-Client die Anfragen an den REST-Controller weiterleitet.
Beim Absenden des Formulars erstellt die clientseitige Methode `SubmitApplication` ein neues `EngineerApplication`-Objekt und befüllt es mit den Formulardaten. Der Status wird dabei automatisch auf „Published" gesetzt, zusammen mit den Zeitstempeln für Einreichung und Genehmigung. Die Methode unterscheidet anhand der `ApplicationId`, ob ein neuer Antrag über den Service `AddApplicationAsync` erstellt oder ein bestehender über `UpdateApplicationAsync` aktualisiert werden soll. Falls keine Datei ausgewählt wurde, wird der Vorgang mit einer entsprechenden Fehlermeldung abgebrochen. Die Kommunikation mit dem Server erfolgt über den injizierten `ApplicationService`, der als HTTP-Client die Anfragen an den REST-Controller weiterleitet. Wie die nachfolgende Abbildung zeigt, führt die klare Gestaltung der Benutzeroberfläche den Benutzer im Browser intuitiv durch den Einreichungsprozess und stellt auch den Bearbeitungsstatus des Antrags übersichtlich dar.
![Formular zum Einreichen eines Ingenieur-Antrags. Die klare und minimalistische Gestaltung der Benutzeroberfläche führt den Benutzer intuitiv durch den Einreichungsprozess und stellt nach Abschluss den aktuellen Bearbeitungsstatus des Antrags übersichtlich dar.](./images/04-Florian/ingenieur-antrag-status.png)
![Formular zum Einreichen eines Ingenieur-Antrags](./images/04-Florian/ingenieur-antrag-status.png)
Serverseitig nimmt die Methode `AddApplicationAsync` im `ServerEngineerApplicationService` den Antrag entgegen. Dort wird zunächst geprüft, ob der Benutzer authentifiziert ist und die View-Berechtigung für das Modul besitzt. Die User-ID wird aus dem HTTP-Kontext extrahiert und dem Antrag zugewiesen, um sicherzustellen, dass kein Benutzer Anträge im Namen anderer erstellen kann. Anschließend wird der Antrag über das Repository in der Datenbank persistiert.
@@ -618,9 +618,9 @@ Ein Administrator kann den Antrag entweder genehmigen oder ablehnen. Bei einer G
**Anzeige genehmigter Anträge**
Die Antrags-Listenansicht bildet das zweite zentrale Feature. Premium-Mitglieder sehen alle genehmigten und veröffentlichten Anträge in einer übersichtlichen Kartenansicht. Jede Karte enthält den Titel, den Namen des Autors, die Kurzbeschreibung und das Veröffentlichungsdatum. Über integrierte Schaltflächen können die zugehörigen PDF-Dokumente direkt im Browser betrachtet oder heruntergeladen werden. Der PDF-Viewer wird als modales Fenster mit eingebettetem iFrame realisiert.
Die Antrags-Listenansicht bildet das zweite zentrale Feature. Wie in der nachfolgenden Abbildung zu sehen ist, sehen Premium-Mitglieder alle genehmigten und veröffentlichten Anträge in einer benutzerfreundlichen Kartenansicht und können Titel, Autor sowie Kurzbeschreibung auf einen Blick erfassen. Jede Karte enthält das Veröffentlichungsdatum und integrierte Schaltflächen, über welche das zugehörige PDF-Dokument bei Bedarf direkt im Browser via eingebettetem iFrame betrachtet oder heruntergeladen werden kann.
![Ansicht der genehmigten Ingenieur-Anträge in einer benutzerfreundlichen Kartenansicht. Premium-Mitglieder können hier Titel, Autor und Kurzbeschreibung auf einen Blick erfassen sowie das zugehörige PDF-Dokument bei Bedarf direkt im Browser betrachten oder herunterladen.](./images/04-Florian/ingenieur-antraege-liste.png)
![Ansicht der genehmigten Ingenieur-Anträge](./images/04-Florian/ingenieur-antraege-liste.png)
Die serverseitige Methode `GetApplicationsAsync` steuert dabei die rollenbasierte Zugriffslogik und entscheidet, welche Anträge ein Benutzer sehen darf:
@@ -659,9 +659,9 @@ Administratoren erhalten alle Anträge zurück. Für andere Benutzer werden zun
**Mitgliedersuche und Kontaktfunktion**
Die Mitgliedersuche ermöglicht Premium-Mitgliedern das gezielte Auffinden anderer registrierter Benutzer. Die clientseitige Blazor-Komponente `UserSearch.razor` stellt ein Eingabefeld bereit, über das der Benutzer seinen Suchbegriff eingibt. Bei jeder Suche wird der eingegebene Text an den `ServerUserContactService` auf dem Server übermittelt, der die eigentliche Suchlogik implementiert.
Die in der nachfolgenden Abbildung gezeigte Mitgliedersuche ermöglicht Premium-Mitgliedern das gezielte Auffinden anderer registrierter Benutzer. Die clientseitige Blazor-Komponente `UserSearch.razor` stellt ein Eingabefeld bereit, über das der Benutzer seinen Suchbegriff eingibt. Aus der dann resultierenden Listenansicht heraus ermöglicht eine Kontaktfunktion, Nachrichten sicher an die gefundenen Personen zu senden, ohne deren direkte E-Mail-Adresse offenzulegen. Bei jeder Suche wird der eingegebene Text an den `ServerUserContactService` auf dem Server übermittelt, der die eigentliche Suchlogik implementiert.
![Mitgliedersuche und Kontaktfunktion für Premium-Mitglieder. Die in die Suchergebnisse integrierte Kontaktfunktion ermöglicht es, Nachrichten sicher an die gefundenen Personen zu senden, ohne deren direkte E-Mail-Adresse offenzulegen.](./images/04-Florian/premium-mitglieder-suche.png)
![Mitgliedersuche und Kontaktfunktion für Premium-Mitglieder](./images/04-Florian/premium-mitglieder-suche.png)
Die serverseitige Methode `SearchUsersAsync` prüft zunächst, ob der Suchbegriff mindestens drei Zeichen umfasst, um übermäßig breite Abfragen zu vermeiden, und ob der anfragende Benutzer authentifiziert ist. Anschließend durchsucht sie die Benutzerdatenbank sowohl nach Anzeigenamen als auch nach Benutzernamen, wobei die Suche groß-/kleinschreibungsunabhängig erfolgt. Die Ergebnisse werden auf maximal 20 Treffer begrenzt.