Interaktive Multiple-Choice-App mit schnellem Feedback, Pseudonym-Login, Itemanalyse und PDF-Exports. 40+ Fragensets (JSON + Learning-Objectives) sind enthalten; weitere lassen sich hochladen oder per KI-Generator erstellen.
- Schnellstart
- Übersicht
- Hauptfunktionen
- Fragenset-Schema
- Sicherheitsfeatures
- Voraussetzungen
- Installation & Start
- Konfiguration
Installationsguides: Mac · Windows · VS Code SSH
Admin-Panel testen: 🔐 Anleitung
- Pseudonym-Login, zufällige Fragenreihenfolge, Gewichtung pro Frage.
- Schnellsuche (Titel/Slug/Meta), Sprachenhinweis aus
meta.language, 40+ Fragensets + Upload temporärer User-Sets. - Scoring: Nur-Plus oder Plus/Minus; Zeitlimit optional pro Set oder via
MC_TEST_DURATION_MINUTES(Default 60, leer/0 = kein Limit). - Navigation: Markieren, Überspringen, Seitenleiste; Panic Mode schaltet alle Cooldowns sofort ab.
- Feedback/Erklärungen, Mini-Glossare, erweiterte Erklärungen; Item- & Distraktor-Analyse, Leaderboard.
- Exporte: PDF (LaTeX, Glossar, Bookmarks), CSV aller Antworten, DB-Dump; Admin-Panel für Analytics, Feedback, KI-Generator.
Die App lädt Fragensets aus JSON-Dateien im data/questions_*.json-Format. Erwartet wird ein Objekt mit:
questions: Liste von Fragenmeta: Objekt mit Basis-Metadaten (erforderlich, mindestenslanguage)
question: String (nicht leer)options: Liste mit 3–5 Stringsanswer: Ganzzahl, 0-basierter Index inoptionsexplanation: String (nicht leer)topic: String (nicht leer)weight: Ganzzahl 1, 2 oder 3 (empfohlen, abweichende Werte erzeugen Warnungen)
concept: String (klares Lernziel/Konzept)cognitive_level: String (z. B. „Reproduction“, „Application“, „Analysis“)mini_glossary: Objekt oder Liste mit Begriff/Definition; empfohlen 2–6 Einträge, max. 10 (App-Features nutzen das Glossar intensiv)extended_explanation: erlaubt; Schema sieheKI_PROMPT.mdundGLOSSARY_SCHEMA.md
language(ISO-639-1, z. B.de) – Pflicht- Empfohlen:
title,question_count(wird auf Konsistenz geprüft),difficulty_profile(easy/medium/hard),test_duration_minutes,time_per_weight_minutes,additional_buffer_minutes,created/modified
{
"meta": {
"language": "de",
"question_count": 1,
"difficulty_profile": {"easy": 0, "medium": 1, "hard": 0}
},
"questions": [
{
"question": "1. Was ist die BFS-Besuchreihenfolge ab Knoten A?",
"options": ["A B C D", "A C B D", "A D B C"],
"answer": 0,
"explanation": "BFS besucht erst alle direkten Nachbarn in Einfügereihenfolge.",
"weight": 2,
"topic": "Graph Traversal",
"concept": "BFS visitation order"
}
]
}- Konsistente Terminologie für
topic/concept/cognitive_level, damit Exporte und Analytics sauber gruppieren. - Meta pflegen:
languageist Pflicht;question_count/difficulty_profilesollten mit der tatsächlichen Anzahl/Verteilung übereinstimmen. - Plausible Distraktoren: 3–5 Optionen ähnlicher Länge; kein „Alle/Keine der oben genannten“.
- Mini-Glossar pflegen: 2–6 relevante Begriffe pro Frage, keine Füllwörter.
- Validierung:
python validate_sets.pyausführen, bevor ein Fragenset committet wird; prüft Pflichtfelder, Optionslänge, Answer-Index, Glossargröße, Gewichtungen u. a. - LaTeX/Markdown: Keine LaTeX-Ausdrücke in Backticks; bei Bedarf korrekt escapen (
\\).
Hinweis: Ältere Fragensets können unvollständige Meta-Daten haben (z. B. kein Datum) und erscheinen dann ohne Datum im Auswahlmenü. Neue Fragensets sollten alle Meta-Felder sauber pflegen (language, question_count, difficulty_profile, ggf. created/modified), damit UI und Exporte korrekt funktionieren.
- Musterlösung (PDF) inkl. Mini-Glossar, Hervorhebung korrekter Optionen, LaTeX-Rendering mit Parallelisierung/Timeouts.
- Schnellsuche auf der Startseite (Titel/Slug/Meta) inkl. Sprachenhinweis; temporäre User-Fragensets werden beim Laden bereinigt (Cleanup konfigurierbar).
- Panic Mode: Sobald verbleibende Zeit < Fragen * Schwellenwert, sind Cooldowns für Antworten/Nächste-Frage deaktiviert.
- KI-Generator/Prompts im Admin-Panel; Upload/JSON-Paste für eigene Fragensets mit Validierung und Zeitlimit-Cleanup.
Die App cached gerenderte LaTeX-Formel-Bilder als PNG-Dateien auf der lokalen Festplatte, um Netzwerkaufrufe zur Remote-Render-API zu reduzieren und Exporte zu beschleunigen. Damit der Cache auf Hosts mit begrenztem oder ephemerem Speicher (z. B. Streamlit Community Cloud) nicht unkontrolliert wächst, gibt es automatische Eviction-Mechanismen.
Konfigurierbare Umgebungsvariablen:
- FORMULA_CACHE_DIR: Pfad zum Cache-Verzeichnis (Standard: ./var/formula_cache)
- FORMULA_RENDER_PARALLEL: Anzahl paralleler Render-Jobs für Formeln (Standard: 6)
- FORMULA_CACHE_MAX_FILES: Maximale Anzahl Dateien im Cache (Standard: 100)
- FORMULA_CACHE_MAX_MB: Maximale Gesamtgröße des Caches in MiB (Standard: 50)
- FORMULA_CACHE_TTL_DAYS: Lebensdauer von Cache-Dateien in Tagen (Standard: 7)
Verhalten:
- Vor jedem Schreiben einer neuen Formeldatei wird die Eviction-Routine ausgeführt: Dateien älter als TTL werden zuerst entfernt; danach werden die ältesten Dateien gelöscht, bis sowohl Dateianzahl als auch Gesamtgröße innerhalb der Grenzwerte liegen.
- Auf schreibgeschützten oder nicht verfügbaren Dateisystemen werden Schreibfehler ignoriert und die In-Memory-Fallback-Strategie verwendet. Das verhindert Abstürze auf restriktiven Plattformen.
Empfehlung: Setze konservative Limits für Cloud-Deploys (z. B. FORMULA_CACHE_MAX_MB=50, FORMULA_CACHE_MAX_FILES=100) und überwache die Nutzung in Logs.
Die MC-Test-App setzt auf folgende Sicherheitsmaßnahmen (Versionen werden hier bewusst nicht aufgelistet):
- Kryptographische Session-Tokens (
secrets.token_urlsafe(32)) mit serverseitigem SHA-256-Hashing (user_id + admin_key + token) statt Klartext im Session-State; Re-Auth vor kritischen Aktionen. - Session-Handling mit Inaktivitäts-Timeout (2 Stunden) und Threading-Locks für sicheren Concurrent Access.
- Rate-Limiting für Login/Wiederherstellung (z. B. 3 Fehlversuche → temporäre Sperre, Reset nach Erfolg).
- SQLite-basiertes Audit-Logging aller Admin-Aktionen inkl. Erfolg/Fehlschlag, CSV-Export und Dashboard-Statistiken.
- DSGVO-orientierte Aufbewahrung via Cleanup-Tool (empfohlen: 90 Tage) und optionales Client-IP-Tracking.
- Warnungen bei leerem/unsicherem Admin-Key.
Security Level: 🛡️ VERY HIGH (Enterprise-Grade)
Dokumentation:
- 📘 SECURITY_PHASE3_SUMMARY.md - Technische Details
- 📋 CHANGELOG_SECURITY_PHASE3.md - Vollständiger Changelog
- 📄 PHASE3_ABSCHLUSS.md - User-Guide
- Python: 3.10–3.12 (empfohlen 3.12).
- Abhängigkeiten: Installiere via
pip install -r requirements.txt.
- Klone das Repository.
- Installiere die Abhängigkeiten:
pip install -r requirements.txt
- Starte die App:
streamlit run app.py
- Öffne http://localhost:8501 im Browser.
- Verbinde dein GitHub-Repository mit deinem Streamlit-Cloud-Konto.
- Deploye die App.
- Konfiguriere die Secrets (siehe nächster Abschnitt) im Dashboard deiner Streamlit-Cloud-App.
Die App wird über Umgebungsvariablen (für sensible Daten) und eine Konfigurationsdatei (für nicht-sensible Daten) konfiguriert.
Für die lokale Entwicklung kannst du eine .env-Datei erstellen. Für das Deployment auf Streamlit Cloud müssen diese Variablen als "Secrets" im Dashboard der App hinterlegt werden.
# Beispiel für .env oder Streamlit Cloud Secrets
MC_TEST_ADMIN_USER="dein_admin_user"
MC_TEST_ADMIN_KEY="dein_geheimes_passwort"
APP_URL="https://ihre-streamlit-app.streamlit.app"MC_TEST_ADMIN_USER: Benutzername für den Admin-Login.MC_TEST_ADMIN_KEY: Passwort für den Admin-Login.MC_NEXT_COOLDOWN_NORMALIZATION_FACTOR: Optionaler Skalierungsfaktor für die Wartezeit beim Klick auf „Nächste Frage“ nach dem Lesen von Erklärungen. Standard:0.3(reduziert die Extras); Werte < 1.0 verkürzen die Cooldowns weiter.APP_URL: URL der Streamlit-App für den QR-Code im PDF-Export. (Default:https://mc-test-amalea.streamlit.app)
Zusätzliche Secrets / Umgebungsvariablen (kurz erklärt):
MC_TEST_DURATION_MINUTES: Optionaler Default für die Testdauer (in Minuten) wenn nicht im Fragenset-Meta angegeben. (Default:60; leer/0 = kein Zeitlimit)MC_USER_QSET_CLEANUP_HOURS: Wie viele Stunden temporäre, von Nutzern hochgeladene Fragensets als "stale" gelten und automatisch beim Laden der Startseite entfernt werden können. (Default:24)MC_USER_QSET_RESERVED_RETENTION_DAYS: Aufbewahrungsdauer (Tage) für temporäre Sets reservierter Pseudonyme. (Default:14)MC_AUTO_RELEASE_PSEUDONYMS: Bei1/truewerden unreservierte Pseudonyme nach Inaktivität automatisch freigegeben. (Default: aktiviert)MC_RATE_LIMIT_ATTEMPTS: Anzahl erlaubter fehlgeschlagener Login-/Wiederherstellungs-Versuche bevor Rate-Limiting greift. (Default:3)MC_RATE_LIMIT_WINDOW_MINUTES: Fenstergröße in Minuten für das Rate-Limit. (Default:5)MC_RECOVERY_MIN_LENGTH: Minimale Länge für ein Wiederherstellungs-Geheimwort (Default:6).MC_RECOVERY_ALLOW_SHORT: Falls gesetzt auf1/true, werden kürzere Wiederherstellungs-Geheimwörter erlaubt.EXPORT_COOLDOWN_SECONDS: Wartezeit nach einem Export im Admin-Panel (Default:300Sekunden).EXPORT_JOB_WORKERS: Anzahl paralleler Export-Worker im Export-Job-Skript (Default:2).EXPORTS_DIR: Zielverzeichnis für Exporte im Export-Job-Skript (Default:./exports).ARSNOVA_MAX_OPTION_LENGTH: Max. Antwortlänge für ARSnova-Export (Default:120Zeichen).BENCH_EXPORTS_N: Anzahl PDF-Exporte im Benchmark-Skript (Default:5).
Hinweis: Du kannst diese Werte lokal in einer .env Datei setzen (z.B. für die Entwicklung) oder als Secrets in deiner Deployment-Umgebung (z. B. Streamlit Cloud). Die App liest zuerst Streamlit-Secrets, dann Umgebungsvariablen und schließlich die lokale JSON-Konfiguration mc_test_config.json.
mc_test_config.json (nicht-sensitiv, wird zuletzt ausgewertet) kann u. a. folgende Felder enthalten: scoring_mode, show_top5_public, test_duration_minutes, recovery_min_length, recovery_allow_short, rate_limit_attempts, rate_limit_window_minutes, next_cooldown_normalization_factor, user_qset_cleanup_hours, user_qset_reserved_retention_days.
- Die App liest die Sprache nicht aus URL-Query-Parametern (z. B.
?lang=de). - Sprache wird ausschließlich über den UI-Sprachselektor gesteuert und in der Session gespeichert.
- Möchtest du das Standardverhalten ändern, passe den Default in
i18n/__init__.py(_DEFAULT_LOCALE) an.
Kurzes Beispiel: Setzen des Cleanup-Timeouts
Lokale Shell (temporär für die laufende Shell):
export MC_USER_QSET_CLEANUP_HOURS=1 # Temporäre Fragensets älter als 1 Stunde gelten als stale
streamlit run app.pyBeispiel: Setzen des Normalisierungsfaktors in der Shell (temporär):
export MC_NEXT_COOLDOWN_NORMALIZATION_FACTOR=0.5
streamlit run app.pyAls Streamlit-Cloud-Secret (im Secrets-Editor):
# Im Secrets-Editor der Streamlit-App hinzufügen
MC_NEXT_COOLDOWN_NORMALIZATION_FACTOR: "0.5"Als Streamlit-Cloud-Secret (YAML / UI):
# Im Secrets-Editor der Streamlit-App hinzufügen
MC_USER_QSET_CLEANUP_HOURS: "1"Hinweis: Die App priorisiert Werte in dieser Reihenfolge: Streamlit-Secrets → Umgebungsvariablen → mc_test_config.json.
.
├── .github/ # CI/CD Workflows
├── .streamlit/ # Streamlit-Themes/Config
├── artifacts/ # Export-Artefakte & Beispiel-SVGs
├── data/ # Fragensets (JSON), Pseudonyme, Glossare
├── data-user/ # Temporäre User-Uploads (bereinigbar)
├── db/ # SQLite-Datenbank(en) + Test-WALs
├── docs/ # Slides, Handouts, Feasibility-Studien
├── examples/ # Beispiel-Configs/Prompts
├── exporters/ # Export-Logik (Anki, CSV, PDF-Helfer)
├── helpers/ # Hilfsfunktionen (PDF, Caching, Validierung)
├── i18n/ # Sprachdateien und Defaults
├── orga/ # Orga-Dokumente & KI-Nutzungsguides
├── scripts/ # Build/CI-Helper (z.B. Key-Extraktion)
├── teams/ # Team-/Stakeholder-Material
├── tests/ # Pytest-Suite
├── tools/ # Lokale Dev-Skripte (Bench, Cache, Export)
├── var/ # Cache-Verzeichnisse (z.B. Formel-Cache)
├── .env.example # Beispiel-Env (nicht eingecheckter .env)
├── mc_test_config.json # Nicht-sensitive Default-Konfiguration
├── anki_serif.apkg # Beispiel-Anki-Deck
├── logo.jpg # Logo der App
├── admin_panel.py # Admin-Panel inkl. Audit/Ratelimit
├── app.py # Streamlit-Einstiegspunkt
├── auth.py # Authentifizierung & Session-Management
├── components.py # Wiederverwendbare UI-Komponenten
├── config.py # Laden der Konfiguration und Fragensets
├── database.py # SQLite-Interaktionen
├── logic.py # Kernlogik (Scoring, Navigation, Status)
├── main_view.py # UI-Logik für die Hauptansichten
├── pdf_export.py # PDF-Report-Generierung mit LaTeX & Glossar
├── pacing_helper.py # Pace-/Cooldown-Helfer
├── session_manager.py # Session-State-Verwaltung
├── question_set_validation.py# Validierung von Fragensets
├── validate_sets.py # CLI-Validator für Fragensets
├── requirements.txt # Python-Abhängigkeiten
├── AI_QUESTION_GENERATOR_PLAN.md # Plan für KI-basierte Fragenset-Generierung
├── DEPLOYMENT_FEASIBILITY_STUDY.md # Infrastruktur & Kostenanalyse
├── GLOSSARY_SCHEMA.md # Mini-Glossar-Schema
├── VISION_RELEASE_2.0.md # Strategische Vision & Roadmap
└── README.md # Diese Dokumentation
Wie groß ist dieses Repository?
| Metrik | Wert |
|---|---|
| 📦 Gesamtgröße | ~535 MB |
| 📂 Git-Historie | ~513 MB |
| 📄 Dateien gesamt | 313 Dateien |
| 🐍 Python-Dateien | 100 Dateien |
| 📝 Markdown-Dokumentation | 107 Dateien |
| 🗂️ JSON-Dateien | 60 Dateien |
| 💻 Python-Codezeilen | ~33 200 Zeilen |
| 📁 Hauptverzeichnisse | 17 Verzeichnisse |
Hinweis: Messung: tracked Dateien (~21 MB) plus .git (~513 MB) → ~535 MB Gesamtgröße; lokale .venv-/Cache-Ordner sind nicht berücksichtigt. Die Statistiken können sich mit der Weiterentwicklung des Projekts ändern.
Es gibt kleine Hilfs-Skripte zum Testen und Benchmarking im Ordner tools/:
tools/test_evict.py— Erzeugt Dummy-Dateien im Cache (var/formula_cache) und testet die Eviction-Routine.tools/run_export_test.py— Führt einen einzelnen Musterlösungs-Export durch und schreibt das PDF nachexports/.tools/benchmark_exports.py— Führe N Exporte hintereinander aus (Standard N=5) und schreibe eineexports/benchmark_summary.txt.tools/check_export_stems.py— Prüft die Dateinamen-Generierung für Exporte (Slug-Logik wie in der App).tools/print_cooldowns.py— Druckt alle Cooldown-Varianten pro Gewichtung/Tempo mit aktuellem Normalisierungsfaktor.
Beispiele:
# Eviction smoke test
PYTHONPATH=. python3 tools/test_evict.py
# Single export (shows progress)
PYTHONPATH=. python3 tools/run_export_test.py
# Benchmark with 5 runs
BENCH_EXPORTS_N=5 PYTHONPATH=. python3 tools/benchmark_exports.py
# Check export filename stems (slug logic)
PYTHONPATH=. python3 tools/check_export_stems.py
# Inspect cooldown table with current normalization
PYTHONPATH=. python3 tools/print_cooldowns.py- Folge strikt dem 5‑Schritte-Konfig-Flow aus
KI_PROMPT.md: 1) Thema, 2) Zielgruppe, 3) Fragenanzahl + Verteilung Gewichte 1–3, 4) Optionsanzahl (A/B/C), 5) Kontextmaterial. Immer nur eine Frage stellen, Unklarheiten zuerst klären. - Vor der Generierung: Zusammenfassung der 5 Konfigs in Nutzersprache anzeigen und explizit Bestätigung abwarten („ja/yes“). Keinen JSON ausgeben, bevor bestätigt wurde.
- Sprache: Nutzer*innen-Sprache für Inhalte, JSON-Schlüssel bleiben Englisch. Gewichte → kognitive Stufen zwingend: 1=Reproduction, 2=Application, 3=Analysis;
answerist 0-basiert. - Blueprinting vor JSON:
<scratchpad>mit Planung (Verteilung, Themen, Optionenzahl bei C, Dauerberechnung). Danach genau einjson-Block, kein weiterer Text. - Schema-Pflicht: Fragen mit führender Nummer
"1. ", Optionsanzahl gemäß A/B/C,difficulty_profile= Summe der Gewichte,test_duration_minutesaustime_per_weight_minutes(Standard: 0.5/0.75/1.0) + Buffer 5. - Qualitätsregeln: Distraktoren plausibel und ähnlich lang, kein „All/None of the above“. Mini-Glossar pro Frage (6–10 sinnvolle Terme).
extended_explanation:nullbei Gewicht 1, Objekt mit 2–6 Schritten bei Gewicht 2/3. - Code/LaTeX: Code immer mit
langund Zeilennummern innerhalb des JSON-Strings (\nnutzen); LaTeX doppelt escapen (\\det), Inline-Math$...$. Echte Leerzeilen statt des Literal-Strings"\\n". - Artefakte landen in
exports/und sind.gitignore-geschützt.
- Zugang:
- Wähle auf der Startseite das in den Secrets (
MC_TEST_ADMIN_USER) definierte Admin-Pseudonym aus. - Nach dem Start des Tests erscheint in der Seitenleiste der Bereich "🔐 Admin Panel".
- Gib dort das Admin-Passwort (
MC_TEST_ADMIN_KEY) ein, um vollen Zugriff zu erhalten.
- Wähle auf der Startseite das in den Secrets (
- Funktionen: Das Panel bietet detaillierte Analysen (Item- & Distraktoranalyse), eine Übersicht und Verwaltung für gemeldetes Feedback, Datenexport (CSV, SQL-Dump, PDF-Export) und Systemeinstellungen (Scoring-Modus, Zurücksetzen der Testdaten).
pip install -r requirements.txt
PYTHONPATH=. pytest- App startet nicht: Stelle sicher, dass alle Abhängigkeiten aus
requirements.txtinstalliert sind.
Beiträge sind willkommen! Forke das Repository, erstelle einen Branch und öffne einen Pull Request.