diff --git a/.gitea/workflows/docs.yml b/.gitea/workflows/docs.yml index 756953c..3efc73d 100644 --- a/.gitea/workflows/docs.yml +++ b/.gitea/workflows/docs.yml @@ -1,34 +1,28 @@ name: Build docs on: - pull_request: + push: + branches: [main] jobs: build-docs: runs-on: ubuntu-latest + container: + image: git.kjan.de/actions/runner-latex:latest env: # Edit here with the names of your latex file and directory (can use ".") DIR: docs FILE: projektdokumentation.tex steps: - name: Checkout - uses: actions/checkout@v2 - - - name: Install TeXlive - env: - ACCEPT_EULA: y - DEBIAN_FRONTEND: noninteractive - run: | - echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | sudo debconf-set-selections - sudo apt-get update && sudo apt-get install texlive-lang-german texlive-xetex texlive texlive-publishers texlive-science latexmk cm-super ttf-mscorefonts-installer -y - sudo fc-cache -f -v + uses: actions/checkout@v4 - name: LaTeX compile working-directory: ${{ env.DIR }} run: latexmk -pdf -xelatex ${{ env.FILE }} - name: Upload artifacts - uses: https://git.kjan.de/actions/upload-artifact@v3 + uses: https://git.kjan.de/actions/upload-artifact@v4 with: name: Doku path: docs/projektdokumentation.pdf diff --git a/docs/projektdokumentation.tex b/docs/projektdokumentation.tex index 44c3cca..37b95cb 100644 --- a/docs/projektdokumentation.tex +++ b/docs/projektdokumentation.tex @@ -19,6 +19,9 @@ \usepackage{enumitem} \usepackage{tikz} \usetikzlibrary{arrows.meta, positioning} +\usepackage{pdflscape} +\usepackage{afterpage} +\usepackage{needspace} % Seitenränder \geometry{ @@ -77,9 +80,9 @@ \centering \vspace*{2cm} - {\Huge\bfseries Casino Gaming Platform GURWEABSOHN\par} + {\Huge\bfseries Trustworthy Casino\par} \vspace{1.5cm} - {\Large\itshape Projektdokumentation für die IHK-Abschlussprüfung\par} + {\Large\itshape Projektdokumentation für das Mittelstufenprojekt\par} \vspace{2cm} {\large\bfseries Fachinformatiker für Anwendungsentwicklung\par} @@ -87,12 +90,10 @@ {\large \begin{tabular}{ll} - \textbf{Prüfling:} & [Name des Prüflings] \\ - \textbf{Prüflingsnummer:} & [Prüflingsnummer] \\ \textbf{Ausbildungsbetrieb:} & Hitec GmbH \\ - \textbf{Projektbetreuer:} & [Betreuer] \\ - \textbf{Projektdauer:} & 70 Stunden \\ - \textbf{Abgabedatum:} & \today \\ + \textbf{Projektbetreuer:} & Herr Heidemann / Frau Deeken \\ + \textbf{Projektdauer:} & 10 Wochen \\ + \textbf{Abgabedatum:} & 12.06.2025 \\ \end{tabular} \par} @@ -109,17 +110,16 @@ \chapter{Beschreibung} \section{Umfeld} -Das Projekt wurde im Rahmen der Abschlussprüfung zum Fachinformatiker für Anwendungsentwicklung bei der Hitec GmbH entwickelt. +Das Projekt wurde im Rahmen des Mittelstufenprojektes entwickelt. \subsection{Produktportfolio der Hitec GmbH} -Die Hitec GmbH ist ein innovatives IT-Unternehmen, das sich auf die Entwicklung moderner Webanwendungen und digitaler Lösungen spezialisiert hat. Das Unternehmen deckt ein breites Spektrum an Technologien ab, von klassischen Enterprise-Anwendungen bis hin zu modernen Cloud-nativen Lösungen. +Die Hitec GmbH ist ein innovatives IT-Unternehmen, das sich auf die Entwicklung moderner Webanwendungen und digitaler Lösungen spezialisiert hat. Das Unternehmen deckt ein breites Spektrum an Technologien ab. \subsection{Weg zur Produktidee} Die Casino Gaming Platform entstand als LF08 Projekt mit dem Ziel, eine vollständige Online-Casino-Plattform zu entwickeln. Die Produktidee basiert auf: \begin{itemize} \item \textbf{Gamification-Trend:} Wachsende Nachfrage nach Online-Gaming-Plattformen - \item \textbf{Technologie-Demonstration:} Showcase moderner Full-Stack-Entwicklung (Angular 20 + Spring Boot 3.5) \item \textbf{Bildungsziel:} Praktische Anwendung von Enterprise-Patterns und modernen Web-Technologien \item \textbf{Marktforschung:} Integration aktueller Standards (OAuth2, Stripe, responsive Design) \end{itemize} @@ -182,14 +182,14 @@ Detaillierte Beschreibung des Problems oder der Marktlücke, welche unser Produk \chapter{Durchführung} \section{Vorgehensweise} -Für die Projektdurchführung wurde Scrum als Vorgehensmodell gewählt. Dadurch wird am Anfang des Projektes und eines Sprints festgelegt, was gemacht werden soll, und jeder ist auf dem gleichen Wissensstand. Des Weiteren gibt es tägliche Updates vom Fortschritt, Probleme können schnell erkannt und angesprochen werden. Dazu kann man auch neue Anforderungen flexibel mit einbringen. +Für die Projektdurchführung wurde Scrum als Vorgehensmodell gewählt bzw. vorgeschrieben. Dadurch wird am Anfang des Projektes und eines Sprints festgelegt, was gemacht werden soll, und jeder ist auf dem gleichen Wissensstand. Des Weiteren gibt es tägliche Updates vom Fortschritt, Probleme können schnell erkannt und angesprochen werden. Dazu kann man auch neue Anforderungen flexibel mit einbringen. \subsection{Verwendete Tools und Methoden} \begin{itemize} \item \textbf{Scrum:} Agile Projektmanagement-Methodik \item \textbf{Jira:} Ticketing und Sprint-Planning \item \textbf{Git:} Versionskontrolle mit Feature-Branch-Workflow - \item \textbf{CI/CD:} Automatisierte Build- und Deployment-Pipelines + \item \textbf{CI/CD:} Automatisierte Build- und Deployment-Pipelines welche gleichzeitig auch die Qualitätssicherung übernimmt \end{itemize} \section{Umsetzung} @@ -266,33 +266,203 @@ Guards → Components → Services → HTTP Interceptors → Backend APIs Angular Router → Lazy Loading → Feature Modules \end{verbatim} -\subsection{Systemarchitektur} -Die Casino Gaming Platform basiert auf einer modernen Microservice-Architektur mit klarer Trennung zwischen Frontend und Backend. +\subsection{Systemarchitektur nach C4-Modell} +Die Casino Gaming Platform basiert auf einer modernen, schichtbasierten Architektur mit klarer Trennung zwischen Frontend und Backend. Die Darstellung erfolgt mittels des C4-Architekturmodells (Context, Container, Component, Code), welches eine hierarchische Sichtweise auf die Softwarearchitektur ermöglicht. -\subsubsection{Gesamtarchitektur} +\clearpage +\begin{landscape} +\subsubsection{Ebene 1: Systemkontext-Diagramm} +Das Systemkontext-Diagramm stellt die Casino Gaming Platform in ihrem geschäftlichen Umfeld dar und zeigt die Beziehungen zu externen Akteuren und Systemen. Es verdeutlicht, wer das System nutzt und mit welchen externen Systemen es interagiert. + +\vspace{0.5cm} \begin{tikzpicture}[ - box/.style={rectangle, draw, minimum width=3cm, minimum height=1.5cm, align=center}, - ->, >=Stealth, node distance=2cm and 1.5cm + person/.style={rectangle, draw=blue!80, fill=blue!15, minimum width=3cm, minimum height=1.8cm, align=center, rounded corners=3pt, thick}, + system/.style={rectangle, draw=blue!80, fill=blue!60, minimum width=5cm, minimum height=2.5cm, align=center, text=white, rounded corners=5pt, thick}, + external/.style={rectangle, draw=gray!80, fill=gray!20, minimum width=3.5cm, minimum height=1.8cm, align=center, rounded corners=3pt, thick}, + ->, >=Stealth, node distance=4cm, thick ] -% Top row -\node[box] (angular) {Angular\\Frontend}; -\node[box, right=of angular] (spring) {Spring Boot\\Backend}; -\node[box, right=of spring] (postgres) {PostgreSQL\\Database}; +% Akteure +\node[person] (player) at (-8, 3) {\textbf{Casino-Spieler}\\Nutzt die Plattform\\für Online-Gaming}; +\node[person] (admin) at (-8, -3) {\textbf{System-Administrator}\\Verwaltet Plattform\\und Benutzer}; -% Bottom row -\node[box, below=of angular] (keycloak) {Keycloak\\Auth Server}; -\node[box, below=of spring] (stripe) {Stripe API\\Payment}; +% Hauptsystem +\node[system] (casino) at (0, 0) {\textbf{Casino Gaming Platform}\\Bietet Online-Casino-Spiele\\mit virtueller Währung und\\Zahlungsabwicklung}; -% Arrows top row -\draw (angular) -- (spring); -\draw (spring) -- (postgres); +% Externe Systeme +\node[external] (stripe) at (8, 3) {\textbf{Stripe API}\\Zahlungsabwicklung}; +\node[external] (email) at (8, 0) {\textbf{E-Mail-Service}\\Verifizierung \&\\Benachrichtigungen}; +\node[external] (oauth) at (8, -3) {\textbf{OAuth-Provider}\\GitHub, Google}; -% Arrows to bottom row -\draw (angular.south) -- (keycloak.north); -\draw (spring.south) -- (stripe.north); +% Beziehungen +\draw (player) -- (casino) node[midway, above] {Spielt Spiele, tätigt Einzahlungen}; +\draw (admin) -- (casino) node[midway, below] {Administriert System}; +\draw (casino) -- (stripe) node[midway, above] {Verarbeitet Zahlungen}; +\draw (casino) -- (email) node[midway, above] {Sendet E-Mails}; +\draw (casino) -- (oauth) node[midway, below] {Authentifiziert Benutzer}; \end{tikzpicture} +\end{landscape} + +\clearpage +\begin{landscape} +\subsubsection{Ebene 2: Container-Diagramm} +Das Container-Diagramm zeigt die High-Level-Architektur der Software und stellt die verschiedenen ausführbaren Einheiten (Container) sowie deren Kommunikation dar. Jeder Container repräsentiert eine separate deploybare/ausführbare Einheit wie eine Webanwendung, Datenbank oder Microservice. + +\vspace{0.5cm} +\begin{tikzpicture}[ + webapp/.style={rectangle, draw=blue!80, fill=blue!25, minimum width=4cm, minimum height=2.5cm, align=center, rounded corners=4pt, thick}, + api/.style={rectangle, draw=green!80, fill=green!25, minimum width=4cm, minimum height=2.5cm, align=center, rounded corners=4pt, thick}, + database/.style={rectangle, draw=red!80, fill=red!25, minimum width=3.5cm, minimum height=2.2cm, align=center, rounded corners=4pt, thick}, + external/.style={rectangle, draw=gray!80, fill=gray!20, minimum width=3.2cm, minimum height=1.8cm, align=center, rounded corners=3pt, thick}, + ->, >=Stealth, node distance=4cm, thick +] + +% Akteur +\node[webapp] (person) at (-10, 5) {\textbf{Casino-Spieler}\\Person\\Nutzt Webbrowser\\oder Mobile App}; + +% Frontend-Container +\node[webapp] (frontend) at (-10, 1) {\textbf{Webanwendung}\\Angular 20, TypeScript\\Liefert statische Inhalte\\und Casino-Spiele-UI}; + +% Backend-Container +\node[api] (backend) at (0, 1) {\textbf{API-Anwendung}\\Spring Boot, Java\\Stellt Spiellogik,\\Benutzerverwaltung und\\Geschäftsregeln bereit}; + +% Datenbank +\node[database] (database) at (0, -4) {\textbf{Datenbank}\\PostgreSQL\\Speichert Benutzerkonten,\\Spielhistorie und\\Transaktionen}; + +% Externe Systeme +\node[external] (stripe) at (9, 4) {\textbf{Stripe API}\\Zahlungssystem}; +\node[external] (email) at (9, 1) {\textbf{Mailpit}\\E-Mail-Service}; +\node[external] (oauth) at (9, -2) {\textbf{OAuth-Provider}\\Authentifizierungsdienste}; + +% Beziehungen +\draw (person) -- (frontend) node[midway, right] {HTTPS}; +\draw (frontend) -- (backend) node[midway, above] {REST API\\JSON/HTTPS}; +\draw (backend) -- (database) node[midway, left] {JDBC\\SQL}; +\draw (backend) -- (stripe) node[midway, above] {HTTPS\\Webhooks}; +\draw (backend) -- (email) node[midway, above] {SMTP}; +\draw (backend) -- (oauth) node[midway, below] {OAuth2\\HTTPS}; + +\end{tikzpicture} +\end{landscape} + +\clearpage +\begin{landscape} +\subsubsection{Ebene 3: Komponenten-Diagramm - Backend API} +Das Komponenten-Diagramm zeigt die interne Struktur des Backend API-Containers und stellt die wichtigsten Softwarekomponenten sowie deren Abhängigkeiten dar. Es verdeutlicht die Architektur nach dem MVC-Pattern mit Controller-, Service- und Repository-Schichten. + +\vspace{0.5cm} +\begin{tikzpicture}[ + component/.style={rectangle, draw=yellow!80, fill=yellow!15, minimum width=3.2cm, minimum height=1.8cm, align=center, rounded corners=3pt, thick}, + controller/.style={rectangle, draw=blue!80, fill=blue!20, minimum width=3.2cm, minimum height=1.8cm, align=center, rounded corners=3pt, thick}, + service/.style={rectangle, draw=green!80, fill=green!20, minimum width=3.2cm, minimum height=1.6cm, align=center, rounded corners=3pt, thick}, + repository/.style={rectangle, draw=orange!80, fill=orange!20, minimum width=3.2cm, minimum height=1.4cm, align=center, rounded corners=3pt, thick}, + ->, >=Stealth, node distance=3cm, thick +] + +% Controller (API-Schicht) +\node[controller] (auth-ctrl) at (-8, 5) {\textbf{Auth Controller}\\Anmeldung, Registrierung,\\OAuth}; +\node[controller] (game-ctrl) at (-3, 5) {\textbf{Spiele-Controller}\\Blackjack, Slots,\\Würfel, etc.}; +\node[controller] (deposit-ctrl) at (2, 5) {\textbf{Einzahlungs-Controller}\\Zahlungs-\\abwicklung}; +\node[controller] (user-ctrl) at (7, 5) {\textbf{Benutzer-Controller}\\Profil-\\verwaltung}; + +% Services (Geschäftslogik-Schicht) +\node[service] (auth-svc) at (-8, 2.5) {\textbf{Auth Service}\\Authentifizierungs-\\logik}; +\node[service] (game-svc) at (-3, 2.5) {\textbf{Spiele-Services}\\Spiellogik und\\Regeln}; +\node[service] (balance-svc) at (2, 2.5) {\textbf{Guthaben-Service}\\Transaktions-\\verwaltung}; +\node[service] (user-svc) at (7, 2.5) {\textbf{Benutzer-Service}\\Benutzer-\\verwaltung}; + +% Repositories (Datenschicht) +\node[repository] (user-repo) at (-5.5, 0) {\textbf{Benutzer-Repository}\\JPA/Hibernate}; +\node[repository] (game-repo) at (-0.5, 0) {\textbf{Spiele-Repository}\\JPA/Hibernate}; +\node[repository] (transaction-repo) at (4.5, 0) {\textbf{Transaktions-Repo}\\JPA/Hibernate}; + +% Sicherheitskomponenten +\node[component] (security) at (-13, 2.5) {\textbf{Security Config}\\JWT-Filter,\\CORS, OAuth2}; + +% Relationships +\draw (auth-ctrl) -- (auth-svc); +\draw (game-ctrl) -- (game-svc); +\draw (deposit-ctrl) -- (balance-svc); +\draw (user-ctrl) -- (user-svc); + +\draw (auth-svc) -- (user-repo); +\draw (game-svc) -- (game-repo); +\draw (balance-svc) -- (transaction-repo); +\draw (user-svc) -- (user-repo); + +\draw (security) -- (auth-svc); + +\end{tikzpicture} +\end{landscape} + +\clearpage +\begin{landscape} +\subsubsection{Ebene 4: Code-Diagramm - Blackjack Service Implementierung} +Das Code-Diagramm zeigt exemplarisch die Implementierungsdetails des Blackjack Game Service auf Klassenebene. Es stellt die wichtigsten Klassen, Interfaces und deren Beziehungen dar, die für die Blackjack-Spiellogik verantwortlich sind. + +\vspace{0.5cm} +\begin{tikzpicture}[ + class/.style={rectangle, draw=cyan!80, fill=cyan!15, minimum width=3.5cm, minimum height=3cm, align=center, rounded corners=4pt, thick}, + interface/.style={rectangle, draw=yellow!80, fill=yellow!15, minimum width=3cm, minimum height=2cm, align=center, rounded corners=4pt, thick}, + ->, >=Stealth, node distance=4.5cm, thick +] + +% Interface - mit mehr Abstand +\node[interface] (game-interface) at (0, 6) {\textbf{<>}\\GameService\\+spielStarten()\\+zugVerarbeiten()\\+ergebnisBerechnen()}; + +% Haupt-Service-Klasse +\node[class] (blackjack-service) at (0, 1) {\textbf{BlackjackService}\\implementiert GameService\\- kartendeck: Deck\\- spielRepository: Repository\\+ neuesSpielStarten(einsatz)\\+ ziehen(spielId)\\+ halten(spielId)\\+ verdoppeln(spielId)}; + +% Unterstützende Klassen - mit größerem Abstand +\node[class] (card-deck) at (-8, 1) {\textbf{Kartendeck}\\- karten: List\\+ mischen()\\+ karteGeben()\\+ zurücksetzen()}; + +\node[class] (game-entity) at (8, 1) {\textbf{BlackjackSpielEntity}\\- id: Long\\- spielerKarten: List\\- dealerKarten: List\\- einsatzBetrag: BigDecimal\\- spielZustand: SpielZustand}; + +\node[class] (balance-service) at (0, -3.5) {\textbf{GuthabenService}\\+ guthabenAktualisieren()\\+ ausreichendGuthaben()\\+ transaktionErstellen()}; + +% Beziehungen +\draw (blackjack-service) -- (game-interface) node[midway, right] {implementiert}; +\draw (blackjack-service) -- (card-deck) node[midway, above] {verwendet}; +\draw (blackjack-service) -- (game-entity) node[midway, above] {verwaltet}; +\draw (blackjack-service) -- (balance-service) node[midway, right] {abhängig von}; + +\end{tikzpicture} +\end{landscape} + +\clearpage +\begin{landscape} +\subsubsection{Deployment-Diagramm} +Das Deployment-Diagramm zeigt die Verteilung der Software-Container auf die physische/virtuelle Infrastruktur und stellt die Laufzeitumgebung der Anwendung dar. Es verdeutlicht, wie die verschiedenen Komponenten in der Produktionsumgebung deployed werden. + +\vspace{0.5cm} +\begin{tikzpicture}[ + node/.style={rectangle, draw=gray!80, fill=gray!15, minimum width=5cm, minimum height=4cm, align=center, rounded corners=5pt, thick}, + container/.style={rectangle, draw=blue!80, fill=blue!20, minimum width=3cm, minimum height=2cm, align=center, rounded corners=4pt, thick}, + ->, >=Stealth, node distance=6cm, thick +] + +% Infrastruktur-Knoten +\node[node] (docker-host) at (0, 0) {\textbf{Docker-Host}\\Ubuntu Linux\\Docker Engine 24.x}; + +% Container innerhalb des Docker-Hosts - mit mehr Abstand +\node[container] (nginx) at (-7, 3.5) {\textbf{nginx}\\Webserver\\Port 80/443}; +\node[container] (angular) at (-2, 3.5) {\textbf{Frontend}\\Angular-App\\Statische Dateien}; +\node[container] (spring) at (2, 3.5) {\textbf{Backend}\\Spring Boot\\Port 8080}; +\node[container] (postgres) at (7, 3.5) {\textbf{Datenbank}\\PostgreSQL\\Port 5432}; +\node[container] (mailpit) at (2, -3.5) {\textbf{Mailpit}\\E-Mail-Service\\Port 1025/8025}; + +% Externe Dienste - mit mehr Abstand +\node[node] (cloud) at (9, 0) {\textbf{Cloud-Dienste}\\Stripe API\\OAuth-Provider}; + +% Beziehungen +\draw (nginx) -- (angular); +\draw (spring) -- (postgres); +\draw (spring) -- (mailpit); +\draw (spring) -- (cloud); + +\end{tikzpicture} +\end{landscape} \subsubsection{Backend-Paketstruktur} Das Backend folgt dem Domain-Driven Design (DDD) Ansatz: @@ -335,8 +505,73 @@ Das Backend folgt dem Domain-Driven Design (DDD) Ansatz: .3 UserService.java. } -\subsubsection{Frontend-Modulstruktur} -Das Frontend ist modular aufgebaut mit Feature-Modulen: +\clearpage +\begin{landscape} +\subsubsection{Ebene 3: Komponenten-Diagramm - Frontend-Anwendung} +Das Komponenten-Diagramm zeigt die interne Struktur der Angular Frontend-Anwendung und stellt die modulare Architektur mit Feature-Modulen, Services und Guards dar. Es verdeutlicht die Anwendung des Angular-Framework-Patterns. + +\vspace{0.5cm} +\begin{tikzpicture}[ + module/.style={rectangle, draw=purple!80, fill=purple!20, minimum width=3.5cm, minimum height=2.2cm, align=center, rounded corners=4pt, thick}, + component/.style={rectangle, draw=blue!80, fill=blue!20, minimum width=3cm, minimum height=1.6cm, align=center, rounded corners=3pt, thick}, + service/.style={rectangle, draw=green!80, fill=green!20, minimum width=3cm, minimum height=1.6cm, align=center, rounded corners=3pt, thick}, + guard/.style={rectangle, draw=orange!80, fill=orange!20, minimum width=3cm, minimum height=1.6cm, align=center, rounded corners=3pt, thick}, + ->, >=Stealth, node distance=3.5cm, thick +] + +% Kern-Module +\node[module] (app) at (4, 6) {\textbf{App}\\Haupt-Modul}; +\node[module] (shared) at (-6, 2) {\textbf{Shared}\\Gemeinsame Komponenten}; + +% Feature-Module +\node[module] (auth) at (-1, 2) {\textbf{Auth}\\Anmeldung, OAuth2}; +\node[module] (games) at (3.75, 2) {\textbf{Spiele}\\Blackjack, Slots, Würfel}; +\node[module] (deposit) at (8.25, 2) {\textbf{Einzahlung}\\Stripe}; +\node[module] (home) at (12.25, 2){\textbf{Home}\\Dashboard}; + +% Services +\node[service] (auth-svc) at (-1, -1.5) {\textbf{Auth}\\JWT, Benutzerstatus}; +\node[service] (user-svc) at (12.25, -1.5) {\textbf{User}\\Profil, Guthaben}; +\node[service] (game-svc) at (3.75, -1.5) {\textbf{Spiele}\\API, Logik}; +\node[service] (payment-svc) at (8.25, -1.5) {\textbf{Payment}\\Stripe}; + +% Guards +\node[guard] (auth-guard) at (-1.5, -4.5) {\textbf{Auth}\\Routen-Schutz}; +\node[guard] (http-interceptor) at (2, -4.5) {\textbf{HTTP}\\JWT, CORS}; + +% Relationships +\draw (app) -- (shared); +\draw (app) -- (auth); +\draw (app) -- (games); +\draw (app) -- (deposit); +\draw (app) -- (home); + +\draw (auth) -- (auth-svc); +\draw (games) -- (game-svc); +\draw (deposit) -- (payment-svc); +\draw (home) -- (user-svc); + +\draw (auth-guard) -- (auth-svc); +\draw (http-interceptor) -- (auth-svc); + +\end{tikzpicture} +\end{landscape} + +\subsubsection{Architektur-Zusammenfassung} +Die Casino Gaming Platform implementiert eine moderne, mehrschichtige Architektur, die folgende Prinzipien befolgt: + +\begin{itemize} + \item \textbf{Separation of Concerns:} Klare Trennung zwischen Präsentations-, Geschäftslogik- und Datenschicht + \item \textbf{Modularität:} Feature-basierte Modularisierung sowohl im Frontend als auch Backend + \item \textbf{Skalierbarkeit:} Container-basierte Architektur ermöglicht horizontale Skalierung + \item \textbf{Sicherheit:} Umfassende Sicherheitskonzepte mit JWT, OAuth2 und CORS-Schutz + \item \textbf{Wartbarkeit:} Standardisierte Patterns (MVC, Repository, Service Layer) erleichtern die Wartung +\end{itemize} + +Die C4-Darstellung zeigt die Architektur auf verschiedenen Abstraktionsebenen und ermöglicht es unterschiedlichen Stakeholdern, die für sie relevanten Aspekte zu verstehen - von der Geschäftslogik bis hin zu technischen Implementierungsdetails. + +\subsubsection{Frontend-Paketstruktur (Detailansicht)} +Die detaillierte Paketstruktur des Frontend zeigt die modulare Organisation: \dirtree{% .1 app/feature/. diff --git a/frontend/angular.json b/frontend/angular.json index a9f9a84..d8c3879 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -21,7 +21,8 @@ { "glob": "**/*", "input": "public" - } + }, + "src/assets" ], "styles": [ "src/styles.css" diff --git a/frontend/src/app/feature/game/blackjack/components/animated-number/animated-number.component.ts b/frontend/src/app/feature/game/blackjack/components/animated-number/animated-number.component.ts index 6e61c0e..9b07eee 100644 --- a/frontend/src/app/feature/game/blackjack/components/animated-number/animated-number.component.ts +++ b/frontend/src/app/feature/game/blackjack/components/animated-number/animated-number.component.ts @@ -61,6 +61,9 @@ export class AnimatedNumberComponent implements OnChanges, AfterViewInit { this.countUp = new CountUp(this.numberElement.nativeElement, this.value, { startVal: this.previousValue, duration: this.duration, + decimalPlaces: 2, + useEasing: true, + useGrouping: false, easingFn: (t, b, c, d) => { if (this.ease === 'power1.out') { return c * (1 - Math.pow(1 - t / d, 1)) + b; diff --git a/frontend/src/app/feature/home/home.component.html b/frontend/src/app/feature/home/home.component.html index b0b77d3..9b79a9e 100644 --- a/frontend/src/app/feature/home/home.component.html +++ b/frontend/src/app/feature/home/home.component.html @@ -4,7 +4,7 @@
-
+

Alle Spiele

@@ -18,24 +18,54 @@
-
-
-
- -
+
+ +
+
+
+
-

{{ game.name }}

- +
+

{{ game.name }}

+ +
+
+
+
+
+ + +
+
+
+ +
+
+

{{ game.name }}

+ +
@@ -43,53 +73,5 @@
- -
-
-

Konto

-
- - - - -
-
- - - -
-

Letzte Transaktionen

-
-
-
-

{{ transaction.status }}

-

- {{ transaction.createdAt | date: 'd.m.y H:m' }} -

-
- - {{ transaction.amount | currency: 'EUR' }} - -
-
-
-
diff --git a/frontend/src/app/feature/home/home.component.ts b/frontend/src/app/feature/home/home.component.ts index ef947f9..f032246 100644 --- a/frontend/src/app/feature/home/home.component.ts +++ b/frontend/src/app/feature/home/home.component.ts @@ -1,34 +1,18 @@ -import { ChangeDetectionStrategy, Component, inject, OnInit } from '@angular/core'; -import { AsyncPipe, CurrencyPipe, DatePipe, NgFor } from '@angular/common'; -import { DepositComponent } from '../deposit/deposit.component'; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { NgFor } from '@angular/common'; import { ActivatedRoute, Router } from '@angular/router'; -import { ConfirmationComponent } from '@shared/components/confirmation/confirmation.component'; import { Game } from 'app/model/Game'; -import { Observable } from 'rxjs'; -import { TransactionService } from '@service/transaction.service'; import format from 'ajv/dist/vocabularies/format'; -import { TransactionHistoryComponent } from '../transaction-history/transaction-history.component'; -import { TransactionData } from '../../model/TransactionData'; @Component({ selector: 'app-homepage', standalone: true, - imports: [ - CurrencyPipe, - NgFor, - DepositComponent, - ConfirmationComponent, - AsyncPipe, - DatePipe, - TransactionHistoryComponent, - ], + imports: [NgFor], templateUrl: './home.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export default class HomeComponent implements OnInit { - isDepositModalOpen = false; isDepositSuccessful = false; - isTransactionModalOpen = false; constructor( public route: ActivatedRoute, @@ -78,35 +62,10 @@ export default class HomeComponent implements OnInit { }, ]; - allGames: Game[] = [...this.featuredGames]; - - recentTransactionData: Observable = - inject(TransactionService).getUsersTransactions(5); - - openDepositModal() { - this.isDepositModalOpen = true; - } - - closeDepositModal() { - this.isDepositModalOpen = false; - } - openDepositConfirmationModal() { this.isDepositSuccessful = true; } - openTransactionModal() { - this.isTransactionModalOpen = true; - } - - closeDepositConfirmationModal() { - this.isDepositSuccessful = false; - } - - closeTransactionModal() { - this.isTransactionModalOpen = false; - } - navigateToGame(route: string) { this.router.navigate([route]); } diff --git a/frontend/src/app/feature/landing/landing.component.html b/frontend/src/app/feature/landing/landing.component.html index 2f38d9f..a7cb79e 100644 --- a/frontend/src/app/feature/landing/landing.component.html +++ b/frontend/src/app/feature/landing/landing.component.html @@ -21,13 +21,7 @@ (click)="showRegisterForm()" class="w-full sm:w-auto button-primary px-6 sm:px-8 py-3 shadow-lg" > - Konto erstellen - - }
@@ -46,33 +40,63 @@

Slots

Klassische Spielautomaten

- Jetzt Spielen + @if (isLoggedIn()) { + + Jetzt Spielen + + } @else { + + }
@@ -82,22 +106,42 @@

Dice

Würfelspiel

- Jetzt Spielen + @if (isLoggedIn()) { + + Jetzt Spielen + + } @else { + + }
diff --git a/frontend/src/app/feature/landing/landing.component.ts b/frontend/src/app/feature/landing/landing.component.ts index d354fa4..93b9e84 100644 --- a/frontend/src/app/feature/landing/landing.component.ts +++ b/frontend/src/app/feature/landing/landing.component.ts @@ -23,15 +23,14 @@ import RecoverPasswordComponent from '../auth/recover-password/recover-password. }) export class LandingComponent implements OnInit, OnDestroy { currentSlide = 0; - private autoplayInterval: ReturnType | undefined; authService: AuthService = inject(AuthService); route: ActivatedRoute = inject(ActivatedRoute); showLogin = signal(false); showRegister = signal(false); showRecoverPassword = signal(false); + isLoggedIn = signal(this.authService.isLoggedIn()); ngOnInit() { - this.startAutoplay(); document.body.style.overflow = 'auto'; if (this.route.snapshot.queryParamMap.get('login') === 'true') { this.showLoginForm(); @@ -39,7 +38,6 @@ export class LandingComponent implements OnInit, OnDestroy { } ngOnDestroy() { - this.stopAutoplay(); document.body.style.overflow = 'auto'; } @@ -73,33 +71,13 @@ export class LandingComponent implements OnInit, OnDestroy { prevSlide() { this.currentSlide = this.currentSlide === 0 ? 1 : 0; - this.resetAutoplay(); } nextSlide() { this.currentSlide = this.currentSlide === 1 ? 0 : 1; - this.resetAutoplay(); } goToSlide(index: number) { this.currentSlide = index; - this.resetAutoplay(); - } - - private startAutoplay() { - this.autoplayInterval = setInterval(() => { - this.nextSlide(); - }, 5000); - } - - private stopAutoplay() { - if (this.autoplayInterval) { - clearInterval(this.autoplayInterval); - } - } - - private resetAutoplay() { - this.stopAutoplay(); - this.startAutoplay(); } } diff --git a/frontend/src/app/shared/components/navbar/navbar.component.html b/frontend/src/app/shared/components/navbar/navbar.component.html index 7e010fa..608f3de 100644 --- a/frontend/src/app/shared/components/navbar/navbar.component.html +++ b/frontend/src/app/shared/components/navbar/navbar.component.html @@ -1,40 +1,120 @@ -