diff --git a/Diplomarbeitsbuch-individueller-teil-Florian-Edlmayer.md b/Diplomarbeitsbuch-individueller-teil-Florian-Edlmayer.md index 3109552..9dcc898 100644 --- a/Diplomarbeitsbuch-individueller-teil-Florian-Edlmayer.md +++ b/Diplomarbeitsbuch-individueller-teil-Florian-Edlmayer.md @@ -145,7 +145,39 @@ Der Umfang des Backups besteht aus zwei zentralen Komponenten: 2. Der Ordner "oqtane.server" auf dem Server Damit wird eine vollständige Sicherung der Website ermöglicht, da bei einer reinen Datenbanksicherung wichtige Anwendungsdateien fehlen würden. +```mermaid +graph TD + %% Styling + classDef startEnd fill:#f9f,stroke:#333,stroke-width:2px; + classDef process fill:#d1e8ff,stroke:#0056b3,stroke-width:1px; + classDef critical fill:#ffcccb,stroke:#b30000,stroke-width:1px; + Start((Start: Cronjob 02:30)) --> Init[Initialisierung: set -euo pipefail] + Init --> Vars[Definiere Pfade & PG-Credentials] + + subgraph Sicherungsphase + Dir[Erstelle Verzeichnis: /var/backups/UTC_TS] --> DB[pg_dump -Fc: Custom Format Dump] + DB --> Files[tar -cvpzf: Komprimierung oqtane.server] + end + + Files --> Check{Fehler aufgetreten?} + Check -- Ja --> Mail[Log Error & Abbruch] + Check -- Nein --> Rotate[Lade Liste der Backup-Ordner] + + subgraph Speicherverwaltung [Retention Management] + Rotate --> Count{Anzahl > 30?} + Count -- Ja --> Delete[rm -rf: Lösche älteste Ordner] + Count -- Nein --> Finish[Schließe Log-Eintrag ab] + Delete --> Finish + end + + Finish --> Ende((Ende)) + + %% Zuweisung Klassen + class Start,Ende startEnd; + class Init,Vars,Dir,DB,Files,Rotate,Delete,Finish process; + class Mail critical; +``` Alle Backups werden lokal auf dem Server gespeichert. Diese Backups sind alle zu finden unter: /var/backups Für jedes Backup wird in diesem Verzeichnis ein Unterordner erstellt, dessen Name einen UTC-Zeitstempel enthält. Das ermöglicht eine saubere Trennung der Sicherungsstände und einfache chronologische Zuordnung. @@ -416,6 +448,31 @@ Der zentrale Zweck besteht darin, einen Anreiz für aktives Engagement im Verein Die Entwicklung erfolgte als eigenständiges Oqtane-Modul, wodurch eine nahtlose Integration in die bestehende Vereinswebsite gewährleistet wird. Das Modul nutzt dabei die vom Framework bereitgestellten Mechanismen für Authentifizierung, Autorisierung, Datenbankzugriff und Dateiverwaltung. Die Architektur folgt etablierten Entwurfsmustern wie dem Repository-Pattern, Dependency Injection und dem Service-Layer-Muster. Das kumulative Premium-System mit vollständigem Audit-Trail stellt sicher, dass alle Statusänderungen transparent und nachvollziehbar sind. Die modulare Struktur erlaubt eine einfache Erweiterung um zusätzliche Funktionen, ohne die bestehende Codebasis grundlegend verändern zu müssen. +```mermaid +graph TD + subgraph Client [Client-Seite / WebAssembly] + UI[Index.razor / Apply.razor] --> SvcC[IApplicationService] + end + + subgraph Server [ASP.NET Core Server] + SvcC --> Ctrl[ApplicationController] + Ctrl --> SvcS[IServerApplicationService] + SvcS --> Prem[IPremiumService] + SvcS --> Rep[IApplicationRepository] + end + + subgraph Data [Persistence Layer] + Rep --> EF[EF Core Context] + EF --> DB[(PostgreSQL)] + Prem --> DB + end + + %% Styles + style Client fill:#e1f5fe,stroke:#01579b + style Server fill:#fff3e0,stroke:#e65100 + style Data fill:#f1f8e9,stroke:#33691e +``` + ## 7.2 Funktionalität und Features des Premium-Bereichs Der Premium-Bereich umfasst mehrere miteinander verknüpfte Funktionen, die gemeinsam ein geschlossenes System bilden. @@ -441,6 +498,30 @@ 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. +```mermaid +classDiagram + class EngineerApplication { + +int ApplicationId + +int UserId + +int ModuleId + +int FileId + +string Title + +string ShortDescription + +string Status + +DateTime? SubmittedOn + +DateTime? ApprovedOn + } + + class ModelBase { + +int CreatedBy + +DateTime CreatedOn + +int ModifiedBy + +DateTime ModifiedOn + } + + EngineerApplication --|> ModelBase : inherits +``` + 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. @@ -613,6 +694,29 @@ private bool IsUserPremium(System.Security.Claims.ClaimsPrincipal user) } ``` +```mermaid +flowchart TD + Req([Anfrage auf Premium-Inhalt]) --> Auth{User.Identity.IsAuthenticated?} + + Auth -- Nein --> Guest[Login-Seite anzeigen] + Auth -- Ja --> Admin{Ist Administrator?} + + Admin -- Ja --> Grant[Zugriff gewährt] + Admin -- Nein --> Role{In Rolle 'Premium Member'?} + + Role -- Ja --> Grant + Role -- Nein --> DB{Eintrag in SZUAbsolventenvereinUserPremium?} + + DB -- Nein --> Deny[Premium-Upgrade-Seite anzeigen] + DB -- Ja --> Valid{Ablaufdatum > Heute?} + + Valid -- Ja --> Grant + Valid -- Nein --> Deny + + style Grant fill:#c8e6c9,stroke:#2e7d32 + style Deny fill:#ffcdd2,stroke:#c62828 +``` + Zuerst wird die Oqtane-Rollenzugehörigkeit geprüft, anschließend der datenbankbasierte Premium-Status mit Ablaufdatum. Das kumulative System sorgt dafür, dass bei mehrfacher Vergabe die Laufzeiten addiert und nicht überschrieben werden — ein Mitglied, das während einer laufenden Premium-Mitgliedschaft einen weiteren Antrag genehmigt bekommt, erhält die zusätzlichen 12 Monate auf das bestehende Ablaufdatum aufgeschlagen. Die Zugriffsbeschränkung wird konsequent auf beiden Seiten durchgesetzt: Clientseitig entscheidet die Blazor-Komponente anhand der Benutzerrolle, welche UI-Elemente angezeigt werden. Serverseitig prüft jeder Service-Aufruf die Berechtigung des anfragenden Benutzers über das `[Authorize]`-Attribut mit Policies wie `PolicyNames.ViewModule` und `PolicyNames.EditModule`, bevor Daten zurückgegeben oder Änderungen vorgenommen werden. Dadurch wird sichergestellt, dass selbst bei einer Manipulation der Client-Anfrage keine unberechtigten Zugriffe möglich sind.