Reviewed-on: #11
Lorem Ipsum – Memory Game Webanwendung
Inhaltsverzeichnis
- Projektbeschreibung
- Anforderungen & Features
- Installation & Setup
- Verwendung
- Projektstruktur
- Technologie-Stack
- Architektur & Technische Entscheidungen
- Sicherheit
- KI-Werkzeuge & deren Einsatz
- Herausforderungen & Lerneffekte
- Team
Projektbeschreibung
Lorem Ipsum ist eine interaktive Webanwendung, die das Kurzzeitgedächtnis trainiert. Nutzer werden mit zufälligen Texten präsentiert, die sie sich innerhalb einer definierten Zeitspanne einprägen müssen. Nach Ablauf der Zeit reproduzieren sie den Text so akkurat wie möglich. Das System bewertet die Leistung durch Wort-für-Wort-Vergleich und vergibt Punkte.
Die Anwendung ermöglicht soziale Interaktion durch ein globales Leaderboard, auf dem Nutzer ihre Scores veröffentlichen und sich mit anderen Spielern vergleichen können.
Anforderungen & Features
Funktionale Anforderungen
| Feature | Beschreibung |
|---|---|
| Benutzerverwaltung | Benutzer können ein Konto erstellen und erhalten ein eindeutiges Passwort |
| Spielmechanik | Zufällige Texte werden angezeigt und müssen nach Ablauf einer Zeitspanne reproduziert werden |
| Score-System | Automatische Bewertung basierend auf korrekt eingegebenen Wörtern mit Punkt-Vergabe |
| Persönliche Scores | Nutzer können alle ihre bisherigen Scores ansehen und verwalten |
| Globales Leaderboard | Echtzeit-Anzeige der Top 10 Spieler mit ihren besten Scores |
| Nachrichten-System | Nutzer können sich gegenseitig Nachrichten/Challenges schreiben |
Installation & Setup
Voraussetzungen
- Moderner Webbrowser (Chrome, Firefox, Safari, Edge)
- Node.js (optional, nur für lokale Backend-Entwicklung)
- Zugriff auf die Backend-API (
config-service.jsfür API-Konfiguration)
Schnellstart
# 1. Repository klonen
git clone <repository-url>
cd lorem_ipsum
# 2. Abhängigkeiten installieren (falls Backend vorhanden)
npm install
# 3. Applikation starten
# Option A: Mit Live-Server (VS Code Extension)
# Rechtsklick auf index.html → "Open with Live Server"
# Option B: Mit Python (falls vorhanden)
python -m http.server 8000
# Dann öffnen: http://localhost:8000
# Option C: Mit Node.js
npx http-server
Backend-Konfiguration
Die API-Endpoints sind in assets/src/service/config-service.js konfiguriert:
// config-service.js
export const API_BASE_URL = "https://api.example.com";
export const API_VERSION = "v1";
Verwendung
Für neue Benutzer
- Account erstellen: Auf der Startseite auf "Registrieren" klicken
- Login: Mit dem erhaltenen Passwort anmelden
- Spiel spielen: "Spiel Starten" wählen
- Text wird 15 Sekunden lang angezeigt
- Nach Ablauf Text reproduzieren
- Automatische Bewertung wird angezeigt
- Scores verwalten: Persönliche Scores einsehen und ggf. auf Leaderboard hochladen
- Leaderboard: Top 10 Spieler in Echtzeit betrachten
- Nachrichten: Mit anderen Spielern kommunizieren oder Challenges stellen
Beispiel-Workflows
Workflow 1: Account erstellen
Home → Login/Registrieren → Username eingeben → Username und Passwort speichern
Workflow 2: Leaderboard ansehen
Home → Leaderboard → Top 10 wird geladen und angezeigt
Projektstruktur
lorem_ipsum/
├── index.html # Startseite
├── README.md # Dokumentation (diese Datei)
├── pages/
│ ├── login.html # Login/Registrierung
│ ├── home.html # Startseite nach Login
│ ├── play.html # Spielseite
│ ├── scores.html # Persönliche Scores
│ ├── leaderboard.html # Globales Leaderboard
│ └── messages.html # Nachrichts-/Challenge-System
├── js/
│ ├── login.js # Login-Logik & Event-Handler
│ ├── play.js # Spiel-Logik (Timer, Text-Vergleich)
│ ├── leaderboard.js # Leaderboard-Rendering
│ ├── navigation.js # Navigations-Controls
│ └── messages.js # Nachrichten-Funktionalität
├── assets/
│ ├── css/
│ │ └── custom.css # Custom-Styles
│ ├── src/
│ │ ├── service/
│ │ │ ├── user-service.js # User-API-Aufrufe (Login, Register)
│ │ │ ├── leaderboard-service.js # Leaderboard-API-Aufrufe
│ │ │ ├── score-service.js # Score-Management
│ │ │ ├── message-service.js # Nachrichten-API
│ │ │ ├── challenge-service.js # Challenge-API
│ │ │ └── config-service.js # API-Konfiguration & Konstanten
│ │ └── sites/
│ │ └── exampleAPI.js # API-Test/Beispiel
│ └── bootstrap-5.3.8-dist/ # Bootstrap Framework (v5.3.8)
└── pages/
└── [weitere Pages wie oben]
Dateibenennungs-Konventionen
- HTML-Dateien:
kebab-case(z.B.login.html,play.html) - JavaScript-Dateien:
kebab-case(z.B.login.js,play.js,user-service.js) - Service-Dateien: Suffix
-service.js(z.B.score-service.js,leaderboard-service.js) - CSS-Klassen: Bootstrap-Utilities + Custom Selektoren; BEM bei komplexen Komponenten (z.B.
.play-challenge-result__title)
Technologie-Stack
| Layer | Technologie | Version | Begründung |
|---|---|---|---|
| Markup | HTML5 | 5 | Semantische Struktur, barrierefreundlich |
| Styling | Bootstrap CSS | 5.3.8 | Responsive Grid, vordefinierte Komponenten, Accessibility |
| Custom CSS | CSS3 | - | Flexbox/Grid für Layout-Feinheiten, Custom Properties |
| Frontend-Logik | Vanilla JavaScript | ES6+ | Keine externen Abhängigkeiten nötig, vollständige Kontrolle |
| API-Kommunikation | Fetch API | - | Modern, Promise-basiert, Error-Handling via try/catch |
| Versionsverwaltung | Git | - | Nachvollziehbarer Entwicklungsverlauf |
Warum Vanilla JS statt Framework?
- Projekt-Anforderungen sind moderat (keine komplexe State-Verwaltung nötig)
- Fetch API mit async/await bietet ausreichende Abstraktionen
- Schnellere Ladezeiten ohne Framework-Overhead
- Volles Verständnis über den Code ohne "Black Box"-Effekte
Warum Bootstrap?
- Responsive Design out-of-the-box (12er Grid-System)
- Umfangreiches Komponenten-Portfolio (Modals, Forms, Cards)
- WCAG Level A Compliance bereits implementiert
- Konsistentes Design über alle Seiten hinweg
Architektur & Technische Entscheidungen
Service-orientierte Architektur
Die Anwendung folgt einer Service-orientierten Architektur:
UI Layer (HTML/CSS)
↓
Event Handler (login.js, play.js, ...)
↓
Service Layer (user-service.js, score-service.js, ...)
↓
Fetch API → Backend REST API
Vorteile:
- Separation of Concerns: Jeder Service hat eine klare Verantwortung
- Wiederverwendbarkeit: Services können von mehreren Seiten genutzt werden
- Testbarkeit: Services können isoliert getestet werden
- Wartbarkeit: API-Änderungen erfordern nur Anpassung in einem Ort
Datenfluss beim Spielen
1. play.js: generateGameText() // Zufälligen Text lokal generieren
2. play.js: Timer starten (15s)
3. User tippt Text ein
4. play.js: Wort-für-Wort-Vergleich nach Position
5. score-service.postScore() // Score zum Server senden
6. UI zeigt Ergebnis sofort an, Speichern läuft asynchron
Authentifizierungs-Design
Besonderheit: Backend generiert Passwörter statt User-Input
Konventionell (problematisch): Unser Ansatz (bewusst gewählt):
User gibt Passwort ein → Backend generiert zufälliges Passwort
Risiko: User nimmt häufig genutztes → Keine Passwort-Reuse-Gefahr
Passwort → Für diese Session gültig
Begründung dieser Entscheidung:
- Sicherheitsausrichtung: Nutzer gefährden kein häufig genutztes Passwort (Lernaspekt: User-Sicherheit)
- Frontend-Fokus: Komplexe Auth-Logik (Hashing, Salting) sind nicht im scope dieses Moduls
- Transparenz: Diese Limitierung ist im Code und README dokumentiert – nicht versteckt
Konsequenzen für OWASP:
- ⚠️ localStorage speichert plaintext-Passwort (A07:2021 – nicht konform)
- ✅ Aber: Generierte Passwörter sind Wegwerf-Token, kein häufig genutztes Passwort
HTML5 Semantik
Alle HTML-Dateien nutzen semantisch korrekte Elemente:
<header> <!-- Navigation und Kopfzeile -->
<main>
<section> <!-- Logische Abschnitte -->
<article> <!-- Spielinhalte -->
<form> <!-- Benutzer-Input -->
<footer> <!-- Impressum, Credits -->
Sicherheit
OWASP-Risiken im Kontext dieser Anwendung
1. Cross-Site Scripting (XSS) – A03:2021
Risiko: Nutzer-Input (Scores, Nachrichten) könnte als Code interpretiert werden
Implementierte Maßnahmen:
// ✅ SICHER: Text-Encoding statt HTML-Parsing
const scoreElement = document.createElement('div');
scoreElement.textContent = userScore; // textContent encodiert automatisch
// ❌ NICHT SICHER: scoreElement.innerHTML = userScore
// ✅ SICHER: Template Literals mit textContent
const formattedScore = `User: ${userName}`; // nie mit innerHTML
Begründung: textContent und DOM-APIs encodieren automatisch; innerHTML mit Benutzerdaten ist ein XSS-Vektor.
2. Authentifizierung & Session-Management – A07:2021
Risiko: Passwort-Speicherung im localStorage, plaintext-Übertragung als Custom-Header
Implementierte Maßnahmen:
- ✅ API nutzt HTTPS (TLS-Verschlüsselung für Übertragung)
- ✅ localStorage mit Auth-Daten nur clientseitig (nicht persistent auf Server)
OWASP-Perspektive – nicht konform:
// ❌ Passwort unverschlüsselt im localStorage
localStorage.setItem('auth', JSON.stringify({
username: user,
password: generatedPassword
}));
// ✅ Produktiv würde man verwenden:
// - HTTP-Only Cookies (vom Server gesetzt, nicht via JS zugreifbar)
// - JWT mit Refresh-Token-Rotation
// - OAuth 2.0 / OpenID Connect
Begründung dieser Limitierung: Siehe Abschnitt Authentifizierungs-Design in der Architektur. Die Designentscheidung, dass das Backend Passwörter generiert, minimiert das Reuse-Risiko. Auth-Komplexität ist Backend-Responsibility.
KI-Werkzeuge & deren Einsatz
ChatGPT / Claude – Code-Review & Debugging
Einsatzbereiche:
- Fehlersuche in asynchronen Promise-Ketten
- Code-Style-Verbesserungen (ES6+ Best Practices)
- Regex-Optimierungen für Text-Vergleich
- Generierung visueller Assets: Logo, Icon sowie Challenge-Grafiken für Gewonnen/Verloren/Unentschieden wurden mit ChatGPT erstellt und anschließend im Projekt eingebunden
Kritische Bewertung:
- ✅ Effektiv für: Schnelle Fehlerbehebung, Best-Practice-Vorschläge
- ⚠️ Vorsicht: KI-Vorschläge nicht blind übernehmen, Logik selbst verstehen
- ✅ Angewendet: Alle KI-Vorschläge wurden auf Korrektheit geprüft
GitHub Copilot – Auto-Completion
Einsatzbereiche:
- Service-Boilerplate-Code (Fetch-Aufrufe, Error-Handling)
- Wiederholte DOM-Manipulationen
Kritische Bewertung:
- ✅ Hilfreich für: Reduktion von Boilerplate-Code
- ⚠️ Problematisch: Code-Qualität variiert, manchmal ineffiziente Patterns
- ✅ Angewendet: Nur nach manueller Prüfung und Refactoring integriert
Herausforderungen & Lerneffekte
🔴 Herausforderungen
1. Text-Vergleich mit Sonderzeichen
Problem: Unterschiedliche Behandlung von Umlauten, Leerzeichen, Satzzeichen
Original: "Café"
User-Input: "cafe" // Accent wird nicht erkannt
Lösung:
- Normalisierung mit
String.prototype.normalize('NFD') - Regelwerk für Sonderzeichen-Ignorieren
- Gelernt: Unicode-Handling in JavaScript ist komplex
2. Asynchrone State-Verwaltung
Problem: Race-Conditions bei mehreren parallelen API-Calls
// ❌ PROBLEMATISCH
const data1 = fetch('/users'); // Promise 1
const data2 = fetch('/scores'); // Promise 2
// Welche Promise löst sich zuerst auf?
Lösung:
Promise.all()für parallele Aufrufeasync/awaitfür sequenzielle Aufrufe- Globale Loading-States um UI zu synchronisieren
- Gelernt: Promise-Sequenzierung ist essentiell für konsistente UI
3. Responsive Design auf mobilen Geräten
Problem: Bootstrap Grid bricht bei sehr kleinen Viewports zusammen Lösung:
- Custom Breakpoints mit CSS Media Queries
- Flexbox für flexible Card-Layouts
- Touch-friendly Button-Größen (min 44x44px)
- Gelernt: Mobile-first Approach hätte von Anfang an helfen sollen
🟢 Lerneffekte
| Bereich | Erkenntnis |
|---|---|
| Fetch API & Error-Handling | try/catch bei Async/Await ist unmissbar; HTTP 400/500 Responses sind nicht automatisch Exceptions |
| DOM-Manipulation | Event-Delegation spart Code; querySelector ist ausreichend für diese Projekt-Größe |
| State Management | Ohne centralized Store (Redux, Vuex) führt komplexe State schnell zu Bugs; globale Variablen sind anfällig |
| Git Workflow | Feature-Branches + aussagekräftige Commit-Messages machen Debugging später viel einfacher |
| Accessibility | WCAG nicht als "nice-to-have" sehen; frühe Integration spart viel Refactoring |
| Testing-Ansatz | Manuelles Testen auf mehreren Browsern/Geräten ist zeitaufwendig; automatisierte Tests würden helfen |
💡 Was würde anders gemacht werden
- Service Layer von Anfang an: Hätte API-Changes sehr vereinfacht
- TypeScript: Würde viele Typo-Fehler early-stage finden
- Unit-Tests: Für Score-Logik und Text-Vergleich empfohlen
- CSS-Präprozessor (SASS): Für komplexere Styling-Szenarien hilfreich
Code-Kommentierung & Qualität
Kommentierung-Standard
// ✅ KURZ & AUSSAGEKRÄFTIG (bevorzugt)
// Vergleiche Texte zeichenweise und zähle korrekte Wörter
function compareTexts(original, userInput) { ... }
// ❌ ÜBERFLÜSSIG (code ist selbsterklärend)
// Inkrementiere counter um 1
counter++;
// ⚠️ NUR FÜR NON-OFFENSICHTLICHES
// Normalisiere Unicode-Sequenzen, da Nutzer-Input oft Umlaute enthält (z.B. "Café")
const normalized = str.normalize('NFD');
Naming-Konventionen
- Funktionen: Verb + Substantiv →
getRandomText(),compareScores() - Variablen: aussagekräftig →
userInputText(nichttxtoderu) - Konstanten: UPPER_SNAKE_CASE →
MAX_TEXT_LENGTH = 5000 - Private Funktionen: Prefix
_→_calculateScore()(Convention only)
Team
| Name | Rolle & Verantwortungsbereich |
|---|---|
| Adrian Joost | Projektleitung & Architektur: Gesamtüberblick, Projektinitialisierung, Definition der Schnittstellen sowie Analyse von Sicherheitslücken und Edge-Cases (inkl. „Cheating“-Szenarien). |
| Daniela Studer-Müller | Core-Game-Logic: Implementierung der Spielmechanik, Text-Generierung sowie Entwicklung der Message- und Challenge-Logik. |
| Florin Gartmann | Score-System & Ranking: Entwicklung der Bewertungslogik (Scoring-Algorithmus) und Implementierung des globalen Leaderboards. |
Lizenz
Dieses Projekt ist für Ausbildungszwecke entwickelt worden.
Weitere Ressourcen
Zuletzt aktualisiert: 2026-05-24