Eine Flask-Webanwendung zur Verwaltung von Schülerdaten, Riegen und Disziplinen für Bundesjugendspiele. Das Projekt bietet verbesserte Sicherheit, modulare Architektur und ein separates Admin-Tool zur Offline-Datenvorbereitung.
├── app/ # Flask-Webanwendung
│ ├── __init__.py # App-Factory, Blueprints, DB-Setup
│ ├── database/
│ │ ├── database.py # Haupt-Datenbank-Klasse (Runtime)
│ │ ├── create_data.py # Hilfsskripte für Testdaten
│ │ └── bjs_database_YYYY.db # SQLite-Datenbank (Jahr-basiert)
│ ├── routes/
│ │ ├── auth.py # Login/Logout, Admin-Dashboard, PIN-Verwaltung
│ │ └── input.py # Erfassungs-Flow (Ergebnisse, Abwesenheit)
│ ├── static/
│ │ ├── auth.css # Styles für Login
│ │ └── input.css # Styles für Erfassung
│ └── templates/
│ ├── auth.html # Login-Seite (Station + Admin)
│ ├── input.html # Ergebnis-Erfassung
│ ├── admin_dashboard.html # Admin-Dashboard
│ ├── admin_disziplinen.html # Disziplin-Verwaltung
│ └── dashboard.html # Fortschritts-Übersicht
├── admin/ # Offline-Admin-Tool (Kivy)
│ ├── admin.py # Kivy-App für Riegen-/DB-Verwaltung
│ ├── admin_database.py # DB-Schema und Hilfsfunktionen
│ ├── cli.py # CLI für Headless-Export
│ ├── utils.py # CSV-Import, Riegen-Erstellung
│ ├── main.kv # Kivy-UI-Definition
│ └── test_data.csv # Beispiel-CSV für Import
├── scripts/ # Hilfsskripte
│ ├── start_dev.sh # Entwicklungsserver starten
│ ├── start_prod.sh # Produktionsserver starten
│ └── admin_export.sh # Admin CLI Export-Skript
├── tests/ # Pytest-Tests
├── config.py # Konfigurationsklassen (Dev/Prod/Test)
├── main.py # Flask-App starten
├── requirements.txt # Python-Abhängigkeiten
└── requirements-dev.txt # Entwickler-Abhängigkeiten
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txtErstelle eine .env-Datei im Projektverzeichnis:
SECRET_KEY=dein-geheimer-schluessel-hier
ADMIN_PASSWORD=sicheres-admin-passwort
DB_PATH=app/database/bjs_database_2025.db
STATION_DEFAULT_PIN=123456
STATION_DEFAULT_NAME=Station
STATION_DEFAULT_MAX_LOGINS=1
STATION_DEFAULT_PIN_LENGTH=6python main.pyDie Anwendung läuft auf http://localhost:5000
┌─────────────────┐ CSV-Import ┌──────────────────┐
│ Schülerdaten │ ──────────────────► │ Admin-Tool │
│ (CSV-Datei) │ │ (Kivy/CLI) │
└─────────────────┘ └────────┬─────────┘
│
│ Erstellt DB offline
▼
┌──────────────────┐
│ SQLite-DB │
│ (bjs_YYYY.db) │
└────────┬─────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Admin-Upload │ │ Station-Login │ │ Dashboard │
│ (Web-UI) │ │ (PIN-basiert) │ │ (Fortschritt) │
└────────┬────────┘ └────────┬────────┘ └─────────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────┐
│ Flask-Webanwendung │
│ • Ergebnis-Erfassung │
│ • Abwesenheits-Markierung │
│ • Live-Fortschritts-Tracking │
│ • Disziplin-Konfiguration │
└─────────────────────────────────────────────┘
Das Admin-Tool dient zur Offline-Vorbereitung der Datenbank.
cd admin
python admin.pypython -m admin.cli --csv path/to/schueler.csv --output bjs_database_2025.dbOder mit dem bereitgestellten Skript:
./scripts/admin_export.sh --csv path/to/schueler.csv --output bjs_database_2025.db- CSV-Import: Schülerdaten aus CSV importieren
- Riegen erstellen: Riegenführer anlegen und Schüler zuweisen
- DB exportieren: Fertige Datenbank für Web-App erzeugen
Geschlecht;Klasse;Name;Vorname;Geburtsjahr;Profil
m;5a;Mustermann;Max;2012;False
w;5a;Musterfrau;Maria;2012;True| Spalte | Beschreibung | Beispiel |
|---|---|---|
| Geschlecht | m oder w |
m |
| Klasse | Stufe + Buchstabe | 5a |
| Name | Nachname | Mustermann |
| Vorname | Vorname | Max |
| Geburtsjahr | Geburtsjahr (4-stellig) | 2012 |
| Profil | Sportprofil (True/False) |
False |
| Typ | Authentifizierung | Zugriff |
|---|---|---|
| Station | 6-stelliger PIN | Ergebnis-Erfassung |
| Admin | Admin-Passwort | Dashboard, PIN-Verwaltung, DB |
- Disziplin auswählen
- PIN eingeben (vom Admin bereitgestellt)
- Ergebnisse erfassen
- PIN-Verwaltung: PINs generieren/widerrufen
- DB-Upload: Neue Datenbank hochladen
- Session-Übersicht: Aktive Geräte einsehen
- Disziplin-Konfiguration: Disziplinen verwalten
- Fortschritts-Dashboard: Riegen-Übersicht
Disziplinen können im Admin-Bereich verwaltet werden:
| Einstellung | Beschreibung |
|---|---|
| Name | Frei benennbar (z.B. "Sprint 50m") |
| Format | time (mm:ss) oder distance (Meter) |
| Anzahl Runden | 1-3 Versuche pro Schüler |
GET /admin/disziplinen– Disziplin-ÜbersichtPOST /admin/disziplinen– Disziplin erstellenPUT /admin/disziplinen/<id>– Disziplin bearbeitenDELETE /admin/disziplinen/<id>– Disziplin löschenGET /admin/disziplinen/export– JSON-ExportPOST /admin/disziplinen/import– JSON-Import
- CSRF-Schutz: Flask-WTF für alle Formulare
- Rate-Limiting: Brute-Force-Schutz für Logins
- Geräte-Bindung: PIN nur auf einem Gerät aktiv
- Session-Verwaltung: Admin kann Sessions widerrufen
- Automatische Backups: Vor DB-Upload + regelmäßig
ENV/FLASK_ENVsteuert die Config-Klasse (development,production,testing).enventhält Secrets/DB-Pfad; in ProdDEBUG=False,SESSION_COOKIE_SECURE=TruesetzenDB_PATHkonfiguriert die DB, Uploads/Backups laufen mit SameSite+HttpOnly-Cookies
ENV=development python main.py
# oder via Skript:
./scripts/start_dev.shENV=production HOST=0.0.0.0 PORT=5000 WORKERS=4 TIMEOUT=120 ./scripts/start_prod.sh
# alternativ direkt:
gunicorn -w 4 -b 0.0.0.0:5000 main:appDEBUG=False
SECRET_KEY=<langer-zufälliger-schlüssel>
SESSION_COOKIE_SECURE=True # Bei HTTPS
SESSION_COOKIE_SAMESITE=Lax
SESSION_COOKIE_HTTPONLY=Truepip install -r requirements-dev.txt
pytest
pre-commit install
pre-commit run --all-files- Lint/Format:
black,ruff(Konfiguration inpyproject.toml) - Git-Hygiene:
.env,*.db, Test-Artefakte sind gitignored; keine DB/CSV ins Repo committen.
from app.database.database import Database
db = Database()
backup_path = db.backup_to_file(label="manual")
print(f"Backup erstellt: {backup_path}")Backups werden automatisch erstellt:
- Vor jedem DB-Upload
- Konfigurierbar im Admin-Bereich (Intervall)
- Prüfe im Admin-Dashboard, ob der PIN aktiv ist
- Prüfe, ob der PIN bereits auf einem anderen Gerät verwendet wird
- Widerrufe den PIN und erstelle einen neuen
- Prüfe den DB_PATH in
.env - Stelle sicher, dass die DB-Datei existiert
- Führe ggf. einen DB-Upload durch
- Bei Stations-Login: Erneut mit PIN anmelden
- Bei Admin-Login: Erneut mit Passwort anmelden
Dieses Projekt ist für den internen Schulgebrauch bestimmt.