Diplomarbeitsbuch-individueller-teil-Adam-Gaiswinkler.md aktualisiert
Some checks failed
Word Count / count-words (push) Failing after 31s
Some checks failed
Word Count / count-words (push) Failing after 31s
This commit is contained in:
@@ -1,49 +1,87 @@
|
||||
# Diplomarbeitsbuch
|
||||
|
||||
---
|
||||
|
||||
## 1. Einleitung
|
||||
|
||||
### Ausgangssituation
|
||||
|
||||
### Motivation
|
||||
|
||||
### Kurzbeschreibung des Projekts
|
||||
|
||||
### Persönlicher Aufgabenbereich
|
||||
|
||||
### Abgrenzung der Arbeit
|
||||
|
||||
Die Datenbankinfrastruktur war zum Projektstart bereits vorhanden und wurde nicht im Rahmen dieser Arbeit konzipiert. Die Diplomarbeit beschränkt sich auf die Entwicklung der Anwendungsschicht, bestehend aus CMS-Konfiguration, Modul- und Theme-Entwicklung.
|
||||
|
||||
### Individuelle Themenstellung
|
||||
|
||||
---
|
||||
|
||||
## 3. Projektumfeld & Rahmenbedingungen
|
||||
|
||||
### Einsatz eines bestehenden CMS (Oqtane)
|
||||
|
||||
### Teamarbeit
|
||||
|
||||
Das Projektteam wurde im Verlauf des Projekts von sechs auf drei Personen reduziert.
|
||||
|
||||
### Schulisches Umfeld (HTL)
|
||||
|
||||
### Zeitliche Rahmenbedingungen
|
||||
|
||||
---
|
||||
|
||||
## 4. Technologischer Überblick
|
||||
|
||||
### 4.1 Web-Entwicklung mit ASP.NET & C#
|
||||
|
||||
#### Backend-Logik
|
||||
|
||||
#### API-basierte Kommunikation
|
||||
|
||||
#### Zusammenspiel mit Oqtane
|
||||
|
||||
### 4.2 Oqtane – Überblick
|
||||
|
||||
#### Grundidee & Architektur
|
||||
|
||||
#### Modul- & Theme-Konzept
|
||||
|
||||
#### Vorteile für das Projekt
|
||||
|
||||
### 4.3 CMS-Grundkonfiguration
|
||||
|
||||
#### Initiale Einrichtung
|
||||
|
||||
#### Modul-Integration
|
||||
|
||||
#### Rollen & Berechtigungen
|
||||
|
||||
#### Grundlegende Systemeinstellungen
|
||||
|
||||
---
|
||||
|
||||
## 5. System- und Lösungsarchitektur
|
||||
|
||||
### Gesamtarchitektur des Systems
|
||||
|
||||
### Einordnung von CMS, Modulen und Theme
|
||||
|
||||
### Datenfluss
|
||||
|
||||
### Architekturentscheidungen
|
||||
|
||||
---
|
||||
|
||||
## 6. Entwicklung des Oqtane Themes
|
||||
|
||||
### 6.1 Ziel des Themes
|
||||
|
||||
Im Rahmen des Projekts AlumniHub wurde ein eigenes Theme für das Content-Management-System Oqtane entwickelt. Ziel dieser Entwicklung war es, das Standarddesign von Oqtane vollständig durch eine projektspezifische Benutzeroberfläche zu ersetzen, die den Anforderungen des Absolventenvereins entspricht. Dabei standen Übersichtlichkeit, Benutzerfreundlichkeit sowie eine moderne und konsistente Gestaltung im Vordergrund. Das Theme sollte zudem auf unterschiedlichen Endgeräten – sowohl Desktop als auch mobil – optimal dargestellt werden.
|
||||
|
||||
---
|
||||
|
||||
### 6.2 Technische Umsetzung
|
||||
|
||||
Als technische Grundlage diente die Theme-Architektur von Oqtane. Das Layout wurde in einer Razor-Datei (`Theme.razor`) definiert, welche von der Basisklasse `ThemeBase` erbt. Dadurch stehen zentrale Funktionen wie Seitenzustand (`PageState`), Navigation und Systemeinstellungen automatisch zur Verfügung.
|
||||
@@ -81,28 +119,40 @@ Für den Inhaltsbereich wurden mehrere Panes definiert (z.B. `Top 100%`, `Left 5
|
||||
|
||||
Zusätzlich wurden die Cookie-Consent-Komponente sowie das ControlPanel für Administratoren integriert. Login- und Registrierungsoptionen werden über den `SettingService` aus den Site-Einstellungen geladen, sodass diese ohne Code-Anpassung gesteuert werden können.
|
||||
|
||||
---
|
||||
|
||||
### 6.3 Herausforderungen
|
||||
|
||||
Eine der zentralen Herausforderungen bei der Entwicklung des Themes war die korrekte Filterung der Navigationsseiten. Die von Oqtane bereitgestellten Blazor-Standardkomponenten für die Navigation verhielten sich dabei nicht wie erwartet, da sie auch interne Systemseiten wie Login, Register oder NotFound in der Hauptnavigation ausgaben und keine ausreichende Möglichkeit boten, diese gezielt auszublenden. Aus diesem Grund wurde auf die Standardkomponenten verzichtet und stattdessen eine eigene Implementierung entwickelt. Durch den direkten Zugriff auf `PageState.Pages` sowie eine LINQ-basierte Filterlogik konnten die anzuzeigenden Seiten vollständig kontrolliert und Systemseiten zuverlässig ausgeblendet werden.
|
||||
|
||||
---
|
||||
|
||||
## 7. Umsetzung der Module
|
||||
|
||||
### 7.1 Anmeldetool
|
||||
|
||||
#### Ziel des Moduls
|
||||
|
||||
#### Frontend (Eingabemaske)
|
||||
|
||||
#### Backend-Logik
|
||||
|
||||
#### API-Schnittstelle
|
||||
|
||||
#### Datenauswertung
|
||||
|
||||
#### UX-Überlegungen
|
||||
---
|
||||
|
||||
### 7.2 Hall of Fame
|
||||
|
||||
Das Hall-of-Fame-Modul ist ein Oqtane-Modul, das ehemalige Absolventinnen und Absolventen der Schule auf der Vereinswebseite präsentiert. Es wurde als eigenständiges, wiederverwendbares Modul innerhalb des Oqtane-Frameworks entwickelt und ermöglicht registrierten Benutzerinnen und Benutzern, sich selbst mit einem persönlichen Profil einzutragen. Die Einträge werden erst nach bewusster Veröffentlichung durch die jeweilige Person auf der öffentlichen Seite angezeigt, können als PDF exportiert werden und unterliegen einem Meldesystem zur Qualitätssicherung.
|
||||
|
||||
#### Datenmodell
|
||||
|
||||
Das Modul verwendet zwei Entitäten, die in der Datenbank als Tabellen abgebildet werden.
|
||||
|
||||
**Entität HallOfFame**
|
||||
|
||||
Die zentrale Entität repräsentiert einen einzelnen Absolventeneintrag und wird in der Datenbanktabelle `SZUAbsolventenvereinHallOfFame` gespeichert.
|
||||
|
||||
| Spalte | Datentyp | Beschreibung |
|
||||
|--------|----------|--------------|
|
||||
| `HallOfFameId` | `int` (PK, Auto-Inkrement) | Primärschlüssel |
|
||||
@@ -120,9 +170,13 @@ Die zentrale Entität repräsentiert einen einzelnen Absolventeneintrag und wird
|
||||
| `CreatedOn` | `DateTime` | Erstellzeitpunkt (Audit) |
|
||||
| `ModifiedBy` | `string` | Zuletzt geändert von (Audit) |
|
||||
| `ModifiedOn` | `DateTime` | Zeitpunkt der letzten Änderung (Audit) |
|
||||
|
||||
Die Entität implementiert das Oqtane-Interface `IAuditable`, wodurch die Audit-Felder automatisch vom Framework befüllt werden. Der Fremdschlüssel `ModuleId` verknüpft jeden Eintrag mit einer bestimmten Modulinstanz und ermöglicht so den Multi-Tenant-Betrieb: Mehrere Hall-of-Fame-Module auf verschiedenen Seiten der Website verwalten jeweils unabhängige Datensätze.
|
||||
|
||||
**Entität HallOfFameReport**
|
||||
|
||||
Die zweite Entität bildet einzelne Meldungen zu einem Eintrag ab und wird in der Tabelle `SZUAbsolventenvereinHallOfFameReport` gespeichert.
|
||||
|
||||
| Spalte | Datentyp | Beschreibung |
|
||||
|--------|----------|--------------|
|
||||
| `HallOfFameReportId` | `int` (PK, Auto-Inkrement) | Primärschlüssel |
|
||||
@@ -132,61 +186,93 @@ Die zweite Entität bildet einzelne Meldungen zu einem Eintrag ab und wird in de
|
||||
| `CreatedOn` | `DateTime` | Erstellzeitpunkt (Audit) |
|
||||
| `ModifiedBy` | `string` | Zuletzt geändert von (Audit) |
|
||||
| `ModifiedOn` | `DateTime` | Zeitpunkt der letzten Änderung (Audit) |
|
||||
|
||||
Der Fremdschlüssel zu `SZUAbsolventenvereinHallOfFame` ist mit kaskadierendem Löschen konfiguriert, sodass beim Löschen eines Eintrags automatisch alle zugehörigen Meldungen entfernt werden. Zwischen den beiden Entitäten besteht somit eine 1:n-Beziehung: Ein Eintrag kann beliebig viele Meldungen besitzen.
|
||||
|
||||
#### Datenbankmigrationen
|
||||
|
||||
Die Datenbankstruktur wird über Entity Framework Core Migrationen versioniert verwaltet. Oqtane verwendet ein eigenes Migrationssystem, das auf der Klasse `MultiDatabaseMigration` basiert und die Kompatibilität mit verschiedenen Datenbankanbietern sicherstellt.
|
||||
|
||||
| Migration | Versionsnummer | Inhalt |
|
||||
|-----------|---------------|--------|
|
||||
|-----------|----------------|--------|
|
||||
| `InitializeModule` | `01.00.00.00` | Erstellt die Haupttabelle mit allen Grundspalten (Name, Year, Description, Image, Link, Status, UserId) sowie den Audit-Spalten |
|
||||
| `AddReportingColumns` | `01.00.00.02` | Erweitert die Haupttabelle um die Spalten `IsReported` und `ReportReason` |
|
||||
| `AddReportTable` | `01.00.00.03` | Erstellt die eigenständige Report-Tabelle mit Fremdschlüssel zur Haupttabelle |
|
||||
|
||||
Jede Migration definiert sowohl eine Aufwärts- als auch eine Abwärtsmethode, sodass ein Rollback möglich ist.
|
||||
|
||||
#### Benutzeroberfläche (Razor-Komponenten)
|
||||
|
||||
Das Modul umfasst vier Blazor-Razor-Komponenten.
|
||||
|
||||
**Index.razor – Übersichtsseite**
|
||||
|
||||
Die Übersichtsseite zeigt alle veröffentlichten Einträge in einem responsiven Kartenlayout mit drei Spalten auf Desktop-Breite. Die Funktionalität umfasst eine Echtzeit-Textsuche über Name und Beschreibung, eine umschaltbare Sortierung nach Datum, Name oder Jahrgang sowie eine Kartenanzeige mit Bild, Name, Jahrgang und gekürzter Beschreibung. Administratorinnen und Administratoren sehen zusätzlich Warnmeldungen bei gemeldeten Einträgen und einen Lösch-Button. Angemeldete Benutzerinnen und Benutzer können über einen eigenen Button ihren Eintrag erstellen oder bearbeiten.
|
||||
|
||||
**Edit.razor – Erstellungs- und Bearbeitungsseite**
|
||||
|
||||
Die Edit-Komponente dient sowohl zum Erstellen als auch zum Bearbeiten eines Eintrags. Sie bietet Formularfelder für Name, Jahrgang, Beschreibung (mit Live-Zeichenzähler), Foto-Upload und Link. Über zwei Speicheroptionen kann zwischen Entwurf und Veröffentlichung gewählt werden. Eine Eigentümerprüfung verhindert das Bearbeiten fremder Einträge, und eine Duplikatprüfung verhindert das Erstellen mehrerer Einträge pro Person.
|
||||
|
||||
**Details.razor – Detailseite**
|
||||
|
||||
Die Details-Komponente zeigt einen einzelnen Eintrag in einem zweispaltigen Layout mit unscharfem Bildhintergrund. Administratorinnen und Administratoren sehen bei gemeldeten Einträgen eine Liste aller Meldungen mit Lösch-Button. Ein modaler Dialog ermöglicht die PDF-Vorschau sowie den Download. Die Meldefunktion wird über die zentrale `IReportUI`-Komponente eingebunden.
|
||||
|
||||
**Settings.razor – Moduleinstellungen**
|
||||
|
||||
Die Settings-Komponente bietet eine einfache Oberfläche für Moduleinstellungen über Oqtanes Setting-Service.
|
||||
|
||||
#### Gemeinsame Melde-Komponente (IReportUI)
|
||||
|
||||
Die Meldefunktion in der Detailseite ist nicht direkt im Hall-of-Fame-Modul implementiert, sondern wird über eine zentrale Schnittstelle aus dem Interfaces-Paket eingebunden. Das Hall-of-Fame-Modell implementiert das Interface `IReportable`, das eine Entität als meldbar kennzeichnet. In der Detailseite wird per Dependency Injection eine `IReportUI`-Implementierung injiziert – die konkrete `ReportComponent` stammt dabei aus dem Admin-Modul und stellt den Melden-Button samt modalem Dialog bereit. Die Komponente wird über Blazors `DynamicComponent` dynamisch gerendert. Ist keine Implementierung im Container registriert, wird die Meldefunktion schlicht nicht angezeigt. Dieses Konzept ermöglicht es, die Melde-Oberfläche zentral zu pflegen und in beliebig vielen weiteren Modulen wiederzuverwenden, ohne dass die einzelnen Module die Melde-Logik selbst implementieren müssen.
|
||||
|
||||
#### PDF-Export mit QuestPDF
|
||||
|
||||
Für die Generierung der PDF-Dokumente wird die Open-Source-Bibliothek QuestPDF in der Community-Edition eingesetzt. Im Server-Projekt wurde ein benutzerdefiniertes MSBuild-Target erstellt, das nach jedem Build automatisch die QuestPDF-DLL sowie die plattformspezifischen nativen Bibliotheken in das bin-Verzeichnis des Oqtane-Servers kopiert. Dies ist notwendig, weil Oqtane Module zur Laufzeit dynamisch lädt und QuestPDF native Abhängigkeiten (unter anderem die SkiaSharp-Rendering-Engine) benötigt.
|
||||
|
||||
Das PDF-Design folgt einem Glasmorphismus-Ansatz. Jede Seite hat das Format DIN A4 ohne Ränder. Über die Layers-API von QuestPDF wird das Hintergrundbild von der Inhaltsebene getrennt. Der Name wird in 36 Punkt ExtraBold mit Großbuchstaben und Zeichenabstand dargestellt, der Jahrgang in 15 Punkt mit erhöhtem Zeichenabstand und die Beschreibung in 11 Punkt mit 1,5-fachem Zeilenabstand. Der Glaseffekt wird durch halbtransparente dunkle Hintergründe mit mehrschichtigen Rahmen unterschiedlicher Transparenz erzeugt.
|
||||
|
||||
#### Implementierungsdetails und Problemlösungen
|
||||
|
||||
Während der Entwicklung traten mehrere technische Herausforderungen auf, die im Folgenden zusammen mit ihren Lösungen beschrieben werden.
|
||||
|
||||
##### Bild-Upload-System
|
||||
**Bild-Upload-System**
|
||||
|
||||
In der ursprünglichen Version des Moduls mussten Benutzerinnen und Benutzer eine Bild-URL manuell in ein Textfeld eingeben. Das implementierte Bild-Upload-System ersetzt dies durch eine Blazor-`InputFile`-Komponente mit Live-Vorschau, Fortschrittsanzeige und Lösch-Button. Die Upload-Methode prüft die Dateigröße (maximal 5 MB), öffnet die Datei als Stream und übermittelt sie als `MultipartFormDataContent` an den Server, der den Dateityp serverseitig validiert, einen UUID-Dateinamen generiert und die Datei speichert. Das System unterstützt beide Blazor-Rendering-Modi.
|
||||
|
||||
##### Concurrency Exception beim Löschen
|
||||
**Concurrency Exception beim Löschen**
|
||||
|
||||
Beim Löschen von Einträgen mit vorhandenen Meldungen trat eine `DbUpdateConcurrencyException` auf, verursacht durch Konflikte im Entity Framework Change Tracker. Die Lösung bestand in der Aufteilung der Löschoperation in zwei separate Transaktionen mit jeweils eigenem DbContext: zuerst werden alle zugehörigen Meldungen gelöscht, danach der Haupteintrag.
|
||||
|
||||
##### Kartendesign-Optimierung
|
||||
**Kartendesign-Optimierung**
|
||||
|
||||
Karten hatten ursprünglich unterschiedliche Höhen durch variierende Beschreibungslängen. Die Lösung kombiniert CSS-Flexbox auf dem Kartenelement mit einer Maximalhöhe von 150 Pixeln und `overflow: hidden` auf dem Beschreibungscontainer, sodass alle Karten einer Zeile dieselbe Höhe aufweisen.
|
||||
|
||||
##### Sortier-Toggle
|
||||
**Sortier-Toggle**
|
||||
|
||||
Die ursprünglich fest codierten Sortierrichtungen wurden durch einen Toggle-Button neben dem Sortier-Dropdown ersetzt, der mit einem dynamischen Pfeil-Icon zwischen aufsteigender und absteigender Sortierung umschaltet. Die Sortierlogik ist in einer berechneten Eigenschaft gekapselt, die Suche und Sortierung kombiniert.
|
||||
|
||||
---
|
||||
|
||||
## 8. Projektorganisation & Teamarbeit
|
||||
|
||||
### 8.1 Planung & Meilensteine
|
||||
|
||||
#### Meilensteine
|
||||
|
||||
#### Soll-/Ist-Vergleich
|
||||
|
||||
#### Zeitverzug
|
||||
|
||||
### 8.2 Teamverkleinerung
|
||||
|
||||
#### Downsizing von 6 auf 3 Personen
|
||||
|
||||
#### Neue Aufgabenverteilung
|
||||
|
||||
#### Auswirkungen auf Theme-Entwicklung, Module und Zeitplanung
|
||||
|
||||
---
|
||||
|
||||
## 9. Übergangslösung, Probleme & Learnings
|
||||
|
||||
### 9.1 Übergangslösung (Sommer 2025)
|
||||
@@ -201,8 +287,6 @@ Das Frontend wurde mit HTML, CSS und JavaScript umgesetzt. Die Hauptseite (`inde
|
||||
|
||||
Im Vergleich zu AlumniHub ist die Übergangslösung deutlich schlichter gehalten. Es gibt keine Benutzerkonten, keine Datenbank und keine Verwaltungsfunktionen. Nach dem Absolvententreffen wurde die Seite nicht abgeschaltet, sondern als Feedback-Seite für das Diplomprojekt weitergenutzt. Lehrkräfte, Mitschülerinnen und Mitschüler sowie externe Besucher konnten darüber Feedback abgeben, bis AlumniHub diese Funktion selbst übernahm.
|
||||
|
||||
---
|
||||
|
||||
### 9.2 Probleme
|
||||
|
||||
#### Technische Probleme
|
||||
@@ -213,8 +297,6 @@ Ein großes Problem war der Zeitdruck vor dem ersten Absolvententreffen. Da Alum
|
||||
|
||||
Im Sommer 2025 war die Mitarbeit im Team sehr ungleich verteilt. Viele Teammitglieder waren nicht erreichbar oder haben nicht aktiv am Projekt weitergearbeitet. Nur ein kleiner Teil des Teams hat in dieser Zeit wirklich weitergemacht. Das hat zu einer ungleichen Arbeitsbelastung geführt und den Fortschritt in dieser Phase deutlich verlangsamt.
|
||||
|
||||
---
|
||||
|
||||
### 9.3 Learnings
|
||||
|
||||
#### Technisch
|
||||
@@ -230,13 +312,23 @@ Es hat sich gezeigt, dass eine klare Aufgabenverteilung von Anfang an wichtig is
|
||||
Eine wichtige persönliche Erkenntnis war, dass Eigeninitiative in einem Teamprojekt entscheidend ist. Besonders in Phasen, wo nicht alle aktiv waren, hat sich gezeigt, dass man Aufgaben selbst in die Hand nehmen muss, damit das Projekt vorankommt.
|
||||
|
||||
---
|
||||
|
||||
## 10. Testen & Qualitätssicherung
|
||||
|
||||
### Funktionstests der Module
|
||||
|
||||
### Theme-Tests
|
||||
|
||||
### Usability-Tests
|
||||
|
||||
### Bekannte Einschränkungen
|
||||
|
||||
---
|
||||
|
||||
## 11. Fazit & Ausblick
|
||||
|
||||
### Zielerreichung & Zusammenfassung
|
||||
|
||||
### Persönliche Reflexion
|
||||
### Erweiterungsmöglichkeiten
|
||||
|
||||
### Erweiterungsmöglichkeiten
|
||||
Reference in New Issue
Block a user