Add persistence layer: TOTP auth, game history, restore

- db/ package: async SQLAlchemy engine + Player/Game/Guess models
- api/auth.py: passwordless TOTP login (pyotp), session token via socket auth
- api/history.py: record guesses/points, DB-backed standings, restore
  unfinished games on startup, host-only end_game
- api/__init__.py: auth-gated handlers, accounts map, rejoin via account
- frontend: Auth (QR + code) and History pages, resume/end-game in lobby/table
- docker-compose: real PostgreSQL service wired via DATABASE_URL
- tests_history.py for the persistence/auth layer; refresh CLAUDE.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Tim
2026-06-23 23:09:50 +02:00
parent beaf142ee4
commit 30c32b7714
24 changed files with 1446 additions and 87 deletions
+28
View File
@@ -1,14 +1,39 @@
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: bridzik
POSTGRES_PASSWORD: bridzik
POSTGRES_DB: bridzik
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U bridzik -d bridzik"]
interval: 5s
timeout: 5s
retries: 5
backend:
build: .
environment:
# Async SQLAlchemy URL -> the Postgres service above (asyncpg driver).
DATABASE_URL: postgresql+asyncpg://bridzik:bridzik@db:5432/bridzik
ports:
- "5000:5000"
volumes:
- ./:/app
depends_on:
db:
condition: service_healthy
frontend:
image: node:22-alpine
working_dir: /app
environment:
# Inside the compose network the backend is reachable as `backend`.
VITE_BACKEND_URL: http://backend:5000
volumes:
- ./frontend:/app
ports:
@@ -16,3 +41,6 @@ services:
command: sh -c "npm install && npm run dev -- --host"
depends_on:
- backend
volumes:
pgdata: