Wichtel-Werkstatt: Secret-Santa-App mit Räumen, Ausschlüssen und Recovery-Links
- FastAPI + SQLite, serverseitig gerenderte Templates, mobil-zuerst - Admin-Passwort, einseitige Ausschlüsse, eingefrorene Auslosung - Teilnehmer sehen Ergebnis per Cookie; Einmal-Recovery-Links bei Verlust - Docker/podman-tauglich (Entrypoint mit Privilegien-Drop, SELinux-:z) - Unit-Tests für Auslosung, E2E-Testskript (30 Checks)
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
# Wichtel-Werkstatt 🎅
|
||||
|
||||
Wichteln ohne Zettel-Chaos: Ein Admin erstellt einen Raum, alle melden sich per
|
||||
Link an, Ausschlüsse werden festgelegt (z. B. Ehepartner), dann wird fair
|
||||
ausgelost. Jede Person sieht **nur ihr eigenes Ergebnis** – der Admin sieht
|
||||
keine Zuweisungen.
|
||||
|
||||
## So funktioniert's
|
||||
|
||||
1. **Raum erstellen:** Auf der Startseite Raumname + Admin-Passwort angeben.
|
||||
Es gibt einen Einladungslink und einen 6-stelligen Code zum Weitergeben.
|
||||
2. **Anmelden:** Alle Teilnehmer öffnen den Link und geben ihren Namen ein.
|
||||
Der Browser merkt sich die Teilnahme über ein langlebiges Cookie.
|
||||
Der Admin nimmt über „Selbst mitwichteln" im Panel direkt selbst teil.
|
||||
3. **Ausschlüsse:** Der Admin legt einseitig fest: „A darf nicht B ziehen“.
|
||||
(Ehepaare = zwei Einträge, je einer pro Richtung.)
|
||||
4. **Auslosen:** Ab 3 Teilnehmern. Danach ist der Raum eingefroren –
|
||||
nichts kann mehr geändert werden.
|
||||
5. **Ergebnis:** Jeder Teilnehmer sieht auf seiner Seite, wen er beschenkt.
|
||||
Der Admin sieht nur, *dass* ausgelost wurde – nicht, wer wen gezogen hat.
|
||||
|
||||
**Cookie verloren?** Der Admin kann im Panel jederzeit (auch nach der Auslosung)
|
||||
einen Einmal-Wiederherstellungslink für eine Person erstellen. Damit bekommt
|
||||
sie auf einem beliebigen Gerät ihr Ergebnis zurück. Der Link funktioniert
|
||||
genau einmal und verrät dem Admin weiterhin nichts über die Zuweisungen.
|
||||
|
||||
## Technik
|
||||
|
||||
- Python/FastAPI, serverseitig gerenderte Templates (Jinja2), kein Build-Schritt
|
||||
- SQLite-Datei in einem Volume – dieses Verzeichnis zu sichern ist das komplette Backup
|
||||
- Mobil-zuerst gestaltet, läuft ohne externe CDN/Font-Abhängigkeiten
|
||||
|
||||
## Lokal testen (Bazzite/podman)
|
||||
|
||||
```bash
|
||||
podman build -t wichteln .
|
||||
podman volume create wichtel-data # überlebt Container-Neustarts
|
||||
podman run -d --name wichteln -p 127.0.0.1:8080:8000 \
|
||||
-v wichtel-data:/data wichteln
|
||||
```
|
||||
|
||||
Dann <http://localhost:8080> öffnen. Stoppen/aufräumen:
|
||||
|
||||
```bash
|
||||
podman rm -f wichteln
|
||||
# optional: podman volume rm wichtel-data
|
||||
```
|
||||
|
||||
Alternativ mit Bind-Mount statt Volume (auf SELinux-Systemen wie Bazzite/Fedora
|
||||
ist `:z` für das SELinux-Label nötig):
|
||||
|
||||
```bash
|
||||
podman run -d --name wichteln -p 127.0.0.1:8080:8000 -v "$PWD/data:/data:z" localhost/wichteln
|
||||
```
|
||||
|
||||
Die Compose-Datei funktioniert sowohl mit `docker compose` (Server) als auch
|
||||
mit `podman-compose up -d` lokal.
|
||||
|
||||
## Auf dem Server (docker compose + nginx)
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Der Container lauscht nur auf `127.0.0.1:8000`; davor gehört ein Reverse
|
||||
Proxy – siehe [`nginx.example.conf`](nginx.example.conf). **HTTPS wird dringend
|
||||
empfohlen**, damit Ergebnis-Cookies nicht unverschlüsselt übertragen werden.
|
||||
Die Daten liegen im `./data/`-Verzeichnis neben der Compose-Datei.
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
python3 tests/test_draw.py # Auslosungslogik, ohne Abhängigkeiten
|
||||
```
|
||||
Reference in New Issue
Block a user