Storyteller Shuffler – Von der Idee zum Launch an einem Tag

Meetings sind oft steif. Besonders remote. Icebreaker-Fragen helfen selten — sie sind entweder zu generisch oder unangenehm. Die Idee: Was wäre, wenn man stattdessen kreative Storytelling-Challenges per Slot-Machine zieht? Gestern habe ich genau das gebaut — von der ersten Zeile Code bis zum Live-Deployment in einem einzigen Tag.

Was ist der Storyteller Shuffler?

Eine Web-App für Team-Meetings. Jemand erstellt ein Event, bekommt einen 6-stelligen Access Code und teilt ihn mit dem Team. Jeder Teilnehmer öffnet die Seite, gibt den Code ein und zieht per Slot-Machine-Animation eine zufällige Storytelling-Challenge. 20 Karten in 6 Kategorien (Structure, Character, Concept, Style, Explore, Function), keine wird doppelt vergeben. Nach 24 Stunden löscht sich alles automatisch.

Event erstellen Screenshot

Der Marathon: Was an einem Tag passiert ist

Die Commit-History liest sich wie ein Speedrun:

  1. Grundgerüst — Flask-App mit Redis für shared state und PostgreSQL für Access Logs
  2. Landing Page — Create/Join-Flow, Mobile-first responsive
  3. Access Code System — 6-stellige Codes, ein Event pro IP
  4. Rate Limiting — Flask-Limiter mit Redis-Backend
  5. Geolocation & Analytics — IP-basierte Standorterkennung, Event-Tracking
  6. Tests — Template Rendering Tests, Unit Tests
  7. Deployment — Docker Compose, Gunicorn mit 4 Workern
  8. Feinschliff — Mobile Fix, Robots/Sitemap, Social Meta Tags

Motivation

Auch hier löse ich eine Challenge aus meinem beruflichem Leben. In wenigen Tagen steht ein Community-Event an und ich stand exakt vor dieser Frage: Wie kann ich dieses Event ein wenig interaktiver gestalten? Es gibt viele Tools online, aber die meisten haben treffen nicht den exakten Use-Case, sind kostenpflichtig oder unpassend.

Technische Highlights

Rate Limiting mit Flask-Limiter

Um Missbrauch zu verhindern, ist jede Route rate-limited. Redis dient als Storage-Backend — damit funktioniert es auch mit mehreren Gunicorn-Workern:

from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

limiter = Limiter(
    get_remote_address,
    app=app,
    storage_uri=f"redis://{REDIS_HOST}:{REDIS_PORT}",
    default_limits=["120 per minute"],
    enabled=not bool(os.environ.get("TESTING")),
)

Das enabled-Flag schaltet Limiting in Tests aus — ein kleines Detail, das viel Debugging spart. Redis wird zusätzlich für die State-Verteilung genutzt. Pro Session kann jede Karte immer nur einmal gezogen werden.

Privacy by Design

IP-Adressen werden ausschließlich als gesalzene SHA-256 Hashes gespeichert. Keine Cookies, keine Registration, keine persönlichen Daten. Ich versuche meine Projekte immer so DSGVO-freundlich wie möglich zu gestalten. Außerdem: Wer mag schon Cookie-Banner…

Event erstellen Screenshot

Stack

Komponente Zweck
Flask Web Framework
Redis Shared State, Rate Limiting, TTL
PostgreSQL Access Log
Gunicorn WSGI Server (4 Worker)
Docker Compose Deployment

Live unter storyteller.maexbert.de.

Fazit

Der größte Hebel war der bewusste Verzicht auf Accounts. Jede Hürde vor dem Mitmachen reduziert die Teilnahme drastisch. Ein 6-stelliger Code ist alles, was man braucht. Und die Slot-Machine-Animation? Dieselbe Challenge fühlt sich als gezogene Karte einfach anders an als als Text in einer Liste. Das kleine Ritual macht den Unterschied.