Skip to content

About

Claude Spielerien

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

101 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Web-Jeopardy

Jeopardy-Spiel für Moderation über Beamer oder Screenshare: Startseite mit Team- und Themenauswahl, 5×5-Spielfeld, Frage-Popup mit Punktevergabe. Später ist ein Online-Modus vorgesehen; die Auslieferung erfolgt als Docker-Container.

Spielablauf

Startseite: Teams festlegen (ein Team genügt – dann läuft das Spiel als Übungsmodus ohne Ranking), eine Themenkategorie wählen und die Schwierigkeit von 1 bis 5 einstellen. Beim Start zieht das Spiel aus dem Fragenvorrat der Kategorie ein eigenes 5×5-Spielfeld: fünf Rubriken als Spalten, je fünf Fragen in aufsteigender Härte. Jede Partie bekommt andere Fragen – wer dieselbe noch einmal spielen will, teilt den Link, in dem die Ziehungsnummer steht. Alternativ lässt sich weiterhin ein fertiges Fragenset als JSON-Datei laden.

Auf dem Spielfeld öffnet ein Klick auf eine Karte die Frage; die Musterlösung und die Punktebuttons erscheinen erst nach „Antwort anzeigen". Erst ein Punktebutton wertet die Frage – dann wird die Karte grau. Punkte werden addiert oder abgezogen und fallen nie unter null. Teamnamen lassen sich jederzeit oben ändern, die Punktebuttons übernehmen den Namen sofort. Ein laufendes Spiel übersteht das Schließen des Browsers. Bei „Neues Spiel“ – auch aus der Auswertung – sind Teams, Kategorie, Schwierigkeit, Bedenkzeit, Veto-Zeit und Abzugsregel vorbelegt. Die Ziehung wird erneuert und die Punkte beginnen bei null. Importierte JSON-Spiele bleiben als Vorlage ausgewählt.

Schwierigkeit und Ziehung

Jede Frage im Vorrat trägt eine Stufe von 1 bis 9. Der Regler schiebt darüber ein Fenster von fünf Stufen – eine je Zeile. In jeder Reglerstellung bekommt das Brett damit fünf verschiedene, aufsteigende Stufen: Die 100er-Karte ist immer die leichteste, die 500er immer die schwerste. Die Skala reicht bis 9, weil das Fenster fünf Stufen breit ist und der Regler es um vier Stellungen weiterschiebt:

Regler 100er 200er 300er 400er 500er
1 Locker 1 2 3 4 5
2 Leicht 2 3 4 5 6
3 Ausgewogen 3 4 5 6 7
4 Fordernd 4 5 6 7 8
5 Für Kenner 5 6 7 8 9

Punkte bleiben immer 100 bis 500: Sie ordnen das Brett und sind nur innerhalb einer Partie vergleichbar. Details zum Vorrat stehen in content/README.md.

Fragen bewerten

Über „Fragen bewerten“ auf der Startseite lässt sich die Schwierigkeit zufälliger Fragen kalibrieren: erst Frage, dann Antwort und Bewertung. „Zu schwer“ erhöht den Schwierigkeitswert um 0,2, „zu leicht“ senkt ihn um 0,2; „Schwierigkeit passt“ zählt eine Zustimmung ohne Scoreänderung. Die drei Buttons zeigen die gerundete aktuelle und die benachbarten Stufen. PostgreSQL speichert Score und Historie. Neue Spiele nutzen die gerundete Stufe; laufende und importierte JSON-Spiele bleiben unverändert. Details: Schwierigkeitsbewertung.

Admin-Backend

Unter /admin lassen sich Fragen suchen, bearbeiten, anlegen und löschen sowie SQL-Lieferungen aus content/sql/ einspielen – erst als Testlauf mit Rollback, dann dauerhaft. Jede Änderung landet mit Benutzer im Protokoll. Die Anmeldung übernimmt Authentik am Ingress; lokal genügt ADMIN_AUTH=dev npm run dev:api. Details: Admin-Backend.

Schnellstart

npm install
docker compose up -d postgres api --build
npm run dev          # http://localhost:5173

Skripte

Befehl Zweck
npm run dev Entwicklungsserver
npm run dev:api Fragen-API (benötigt DATABASE_URL)
npm run db:migrate PostgreSQL-Schema migrieren
npm run db:seed Fragen einmalig initialisieren
npm run db:import JSON-Pools bewusst in PostgreSQL übernehmen
npm run test:db Integration gegen separate PostgreSQL-Test-DB
npm run build Produktions-Build nach apps/web/dist
npm run preview Gebautes Ergebnis lokal ausliefern
npm run lint ESLint über das gesamte Monorepo
npm run typecheck TypeScript-Prüfung aller Projekte
npm test Unit- und Komponententests (Vitest)
npm run test:coverage Tests mit Coverage-Schwellen für game-core
npm run test:junit Wie oben, zusätzlich JUnit-Bericht für CI
npm run test:e2e End-to-End-Tests (Playwright)
npm run validate:content Prüft Index und Fragenpools in content/topics
npm run build:info Commit und Datum für die Fußzeile bereitstellen

Continuous Integration

Gebaut und geprüft wird auf jenkins.d39s.de; die Pipeline steht im Jenkinsfile und nutzt die gemeinsame jenkins-library. Zwei Stufen:

  1. Prüfen im playwright-Pod: npm ci, Formatprüfung, Lint, Typecheck, Seed-/Importdaten, Unit- und Komponententests, echte PostgreSQL-Integration und End-to-End-Tests. Ein PostgreSQL-Sidecar mit temporärem Volume stellt eine isolierte Testdatenbank bereit. UI-Browsertests mocken die API; die DB-Tests prüfen Migration, Import, Scores und Speicherung. Die Testberichte entstehen als JUnit unter reports/ und laufen über publishChecks/withChecks als GitHub-Check zurück; der Playwright-Bericht wird als Artefakt gesichert.
  2. Images bauen über den Library-Schritt kaniko, jeweils in einem eigenen Pod. docker/Dockerfile liefert harbor.d39s.de/library/web-jeopardy, docker/api.Dockerfile liefert harbor.d39s.de/library/web-jeopardy-api. Beide nutzen das Repository-Wurzelverzeichnis als Kontext und dieselbe Tag-Strategie. Vor dem Web-Build schreibt die Stufe Commit und Baudatum nach apps/web/.env.production – im Kontext liegt kein .git, sonst bliebe die Fußzeile der Startseite ohne Commit.

Die Tags vergibt die Library: br-<zweig> auf Zweigen, pr-<nummer> bei Pull Requests, latest auf dem Hauptzweig und Versionsnummern aus Git-Tags. Gibt es kein Ziel, baut kaniko mit --no-push – der Build wird also auch dort geprüft, wo nichts veröffentlicht wird.

Eine GitHub-Action gibt es nicht mehr; Jenkins meldet die Ergebnisse als Check nach GitHub zurück.

Betrieb im Container

npm run build:info            # Commit und Datum für die Fußzeile, siehe Versionierung
docker compose up --build     # http://localhost:8080

Compose startet Weboberfläche über nginx, Node-Fragen-API, PostgreSQL 17 und lokales pgAdmin. Die vorhandenen Fragen werden beim ersten API-Start übernommen. Besonderheiten:

  • Persistente Fragen: PostgreSQL speichert Fragen in einem benannten Volume. Die API liefert Themen und Pools über /api/v1; nginx leitet diese Anfragen weiter.
  • Fragen ohne neues Image: per API ändern oder JSON-Pools nach Prüfung mit docker compose exec api npm run db:import übernehmen. Neustarts überschreiben nichts.
  • JSON-Spielimport: fertige Spiele werden weiterhin lokal im Browser importiert, unabhängig von Datenbank und API.
  • Verlaufsadressen: unbekannte Pfade beantwortet index.html, /game funktioniert also auch beim direkten Aufruf.
  • Zwischenspeicher: gehashte Dateien in /assets werden dauerhaft gecacht, index.html, API-Antworten und /config.json bewusst nicht.
  • Laufzeitkonfiguration: Der Einstiegspunkt schreibt config.json aus Umgebungsvariablen (derzeit JEOPARDY_WS_URL als Platzhalter für den späteren Online-Modus), sodass dasselbe Image in mehreren Umgebungen läuft.
  • API-Ziel im Frontend-Pod: JEOPARDY_API_URL setzt beim Containerstart das nginx-Ziel, standardmäßig http://api:3001. In Kubernetes etwa http://jeopardy-api:3001 verwenden, ohne abschließenden Slash oder /api. Browseranfragen bleiben auf /api/v1 derselben Origin.
  • Keine Fragen im Webimage: Die JSON-Pools sind nur Seed-/Importquelle im API-Image und Testdaten im Repository. Das Frontend lädt alle Fragen ausschließlich aus PostgreSQL via API.

Projektstruktur

apps/web/           Oberfläche (React, Vite, Tailwind)
apps/api/           Fragen-API, PostgreSQL-Zugriff, Migrationen und Import
packages/game-core/ Spiellogik ohne Framework-Bezug (Typen, Schemas, Reducer, Ziehung)
content/topics/     JSON-Seed und Importquelle, Laufzeitdaten liegen in PostgreSQL
docker/             Dockerfile, nginx-Konfiguration, Compose
docs/               Konzept, Arbeitsplan, ADRs
e2e/                End-to-End-Tests

Versionierung

Unten auf der Startseite steht, welcher Stand gerade läuft:

Version 2.1.0 · Commit d186d11 · Stand 09.09.2026

So ist auf jedem Beamer und in jedem Screenshot ablesbar, welches Build zu sehen ist. Der Commit-Hash führt per Klick zum Stand im GitHub-Repository.

Maßgeblich ist die version in der package.json im Wurzelverzeichnis. Jede weitere Änderung und jedes Release folgt Semantic Versioning – MAJOR.MINOR.PATCH:

Stufe Wann sie steigt
MAJOR Bruch am Verhalten oder an den Daten, etwa ein neues Schema für Fragensets
MINOR Neue Funktion, abwärtskompatibel
PATCH Fehlerbehebung ohne neue Funktion

Bis 0.2.0 galt eine Vorabphase, in der auch Brüche nur MINOR erhöht haben. Seit 2.1.0 gilt SemVer ohne Ausnahme: Ein Bruch erhöht immer MAJOR. Die Version wandert nicht mit jedem Commit, sondern mit dem Release. Ein Release setzt alle Arbeitsbereiche gemeinsam und legt das Git-Tag an, aus dem die Pipeline die Image-Tags ableitet:

npm version <major|minor|patch> --workspaces --include-workspace-root
git push --follow-tags

Commit und Datum kommen aus dem Build, nicht aus dem Quelltext:

  • Lokal (npm run dev, npm run build) liest Vite den kurzen Commit-Hash direkt aus dem Arbeitsverzeichnis; als Datum gilt der Zeitpunkt des Builds.
  • Im Container gibt es kein .git (siehe .dockerignore). Dort liefert npm run build:info die Angaben vorab als apps/web/.env.production; die Jenkins-Pipeline schreibt dieselbe Datei aus GIT_COMMIT. Fehlt sie, steht in der Fußzeile Commit unbekannt.

Mitarbeiten

Verbindliche Commit-Regeln und Best Practices stehen in docs/arbeitsplan.md (Kapitel 6 und 7). Kurzfassung: Conventional Commits, kleine Commits, main bleibt jederzeit grün, Releases nach SemVer.

About

Claude Spielerien

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages