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:
2026-08-05 16:07:21 +02:00
commit d56be7b2c0
21 changed files with 1839 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
{% extends "base.html" %}
{% block title %}{{ room.name }} Wichtel-Werkstatt{% endblock %}
{% block content %}
<h1 class="room-title">{{ room.name }}</h1>
{% if error %}<div class="alert alert-error" role="alert">{{ error }}</div>{% endif %}
{% if participant %}
{% if drawn %}
<section class="card card-result">
<p class="hello">Ho ho ho, {{ participant.name }}! 🎅</p>
<p class="result-label">Du beschenkst in diesem Jahr:</p>
<p class="result-name">🎁 {{ assignment.receiver_name if assignment else "…" }}</p>
<p class="hint">Verrate es niemandem die Überraschung soll echt sein! 🤫</p>
<p class="hint">Diese Seite merkt sich dein Ergebnis über deinen Browser.
Bleib also auf diesem Gerät oder frage den Admin nach einem neuen Link,
falls du den Zugriff verlierst.</p>
</section>
{% else %}
<section class="card">
<p class="hello">Hi {{ participant.name }}! 👋</p>
<p>Du bist als Wichtel angemeldet. ✅</p>
<p class="waiting">⏳ Jetzt heißt es warten, bis die Auslosung startet.
Schau einfach später nochmal hier vorbei dein Ergebnis erscheint
auf genau dieser Seite.</p>
<p class="hint">Wichtig: Diese Seite merkt sich dich über deinen Browser.
Bitte lösche das Cookie nicht und bleib auf diesem Gerät.</p>
</section>
{% endif %}
{% else %}
{% if drawn %}
<section class="card">
<p>Hier wurde bereits ausgelost eine Teilnahme ist leider nicht mehr möglich. 🎄</p>
</section>
{% else %}
<section class="card">
<h2>Mitmachen</h2>
<p>Gib deinen Namen ein, um bei <strong>{{ room.name }}</strong> mitzuwichteln.</p>
<form method="post" action="/r/{{ room.code }}/register" class="stack">
<label>
Dein Name
<input type="text" name="name" maxlength="50" required
autocomplete="name" placeholder="z. B. Anna">
</label>
<button type="submit" class="btn btn-primary">Mitwichteln 🎁</button>
</form>
<p class="hint">Nach der Anmeldung merkt sich diese Seite dich über deinen
Browser so siehst du später hier dein Ergebnis.</p>
</section>
{% endif %}
{% endif %}
{% endblock %}