Die App verwaltet Bundesjugendspiele als Flask-Webanwendung.
Rollen:
AdminStationEvent
Die Anwendung arbeitet immer mit genau einer aktiven Event-Datenbank.
Startpunkt der App. Importiert create_app() und startet Flask.
App-Factory.
Verantwortlich fuer:
- Laden der Flask-Konfiguration
- Logging
- CSRF
- Fehlerhandler
- Aufloesen der aktiven Event-Datenbank
- Registrieren der Blueprints
Technische Grundbausteine.
settings.pyFlask-Konfiguration fuer Development, Test und Produktionregistry.pyZugriff auf die Meta-Datenbankdisziplinen.pyfeste Disziplindefinitionen und UI-Texte
HTTP-Endpunkte.
auth.pyLogin, Admin-Bereich, Dashboard, Event-Seiten, Import, Export, Backupsinput.pyStations-Erfassung
Fachlogik ohne HTTP-spezifischen Code.
csv_import.pyCSV-Import in Event-Datenbankenriegen.pyRiegenerzeugung und Namensersetzungauswertung.pyPunkteberechnung, Gesamtwertung, Urkunden
SQLite-Zugriffsschicht fuer die Event-Datenbank.
Diese Datei ist die zentrale Stelle fuer:
- Tabellenaufbau
- Migrationen
- CRUD-Zugriffe
- Auswertungsabfragen
- PIN- und Sessionlogik
- Backup-Logik
templates/Jinja-Templatesstatic/CSS und statische Dateien
Es gibt zwei SQLite-Ebenen.
Standardpfad:
database/bjs_meta.db
Zweck:
- registrierte Event-Datenbanken verwalten
- aktive Event-Datenbank merken
- globale Konfigurationswerte speichern
Wichtige Tabellen:
Speichert bekannte Event-Datenbanken.
Wichtige Spalten:
namepathlabelyearcreated_atfile_sizeextra_json
Key-Value-Tabelle fuer globale Werte.
Wichtiger Eintrag:
active_db_path
Historisch als Tabelle vorhanden, fachlich aber statisch.
Die aktuell verwendeten Disziplinen kommen aus app/core/disziplinen.py.
Zweck:
- alle Daten eines einzelnen Events speichern
Wichtige Tabellen:
Stammdaten der Teilnehmer.
Wichtige Spalten:
SchuelerIDNameVornameGeschlechtKlasseKlassenbuchstabeGeburtsjahrBundesjugentspielalterProfilRiegenfuehrerIDGesamtpunktzahlUrkunde
Speichert Riegen und ihre Eigenschaften.
Wichtige Spalten:
IDNameGeschlechtProfilStufeKlassenendungen
Speichert Ergebnisse pro Schueler, Disziplin und Runde.
Wichtige Spalten:
IDSchuelerIDDisziplinErgebnisNRresult_valuestatussource_ipad_numbersource_stationcreated_at
Hinweis:
- dieselbe Runde kann mehrfach gespeichert werden
- fuer Auswertungen wird in der Regel der neueste Eintrag je Schueler/Disziplin/Runde verwendet
PINs fuer Stations-Logins.
Wichtige Spalten:
stationdisciplinepinmax_loginsactive
Aktive Geraetebindungen fuer PINs.
Wichtige Spalten:
pindevice_iddisciplineactive
Key-Value-Tabelle pro Event-Datenbank.
Beispiel:
- Event-PIN
Konfiguration und Verlauf fuer Datenbank-Backups.
Die aktive Event-Datenbank wird ueber die Meta-Datenbank bestimmt.
Ablauf in app/__init__.py:
DbRegistrywird fuer die Meta-Datenbank erzeugt.active_db_pathwird gelesen.- Wenn die Datei existiert, wird sie verwendet.
- Wenn nicht, wird die neueste Datenbank fuer das aktuelle Jahr gesucht.
- Diese wird dann als aktiv gesetzt.
Alle Request-gebundenen Datenbankzugriffe laufen ueber get_db().
Typischer Ablauf:
- Request trifft auf eine Route in
app/routes/ - Route prueft Session, Rolle und Eingaben
- Route holt die aktive Event-Datenbank ueber
get_db() - Route ruft
Database-Methoden oder einen Service auf - Rueckgabe als HTML, Redirect, JSON oder Download
Beteiligte Dateien:
app/routes/auth.pyapp/services/csv_import.pyapp/core/registry.pyapp/database/database.py
Ablauf:
- Admin laedt CSV hoch
- CSV wird gelesen und validiert
- neue Event-Datenbank wird erstellt oder bestehende befuellt
- Datenbank wird in
Db_Registryeingetragen - Datenbank wird aktiv gesetzt
Beteiligte Dateien:
app/routes/auth.pyapp/services/riegen.pyapp/database/database.py
Ablauf:
- vorhandene Klassen werden aus
Schuelergelesen - pro Klasse werden Riegen erzeugt
- Schueler werden ueber Klasse, Profil und Geschlecht zugeordnet
- Platzhalternamen koennen spaeter ersetzt werden
Beteiligte Dateien:
app/routes/auth.pyapp/database/database.py
Ablauf:
- Login mit PIN und Disziplin
claim_station_pin(...)prueft aktive Sessions- PIN wird an ein Geraet gebunden
- Rolle
stationwird in die Session geschrieben
Beteiligte Dateien:
app/routes/input.pyapp/database/database.py
Ablauf:
- Riege wird geladen
- Schuelerliste wird in der Session gehalten
- Ergebnisse werden rundenweise gespeichert
- Status und Fortschritt werden aus Session + DB berechnet
Beteiligte Dateien:
app/services/auswertung.pyapp/routes/auth.pyapp/database/database.py
Ablauf:
- Auswertungskandidaten werden geladen
- Punkte je Disziplin werden berechnet
- niedrigste Disziplin faellt bei vier vorhandenen Werten weg
- Gesamtpunktzahl und Urkunde werden in
Schuelergeschrieben - Export wird pro Klasse als CSV gebaut
Disziplinen sind statisch.
Quelle:
app/core/disziplinen.py
Die Bewertungsparameter sind ebenfalls statisch.
Quelle:
app/services/auswertung.py
Es gibt dafuer keine separate editierbare Konfigurationsdatei mehr.
Datei:
app/database/database.py
Zusatz:
- Migration mitdenken
- lesende und schreibende Methoden anpassen
Datei:
app/services/csv_import.py
Datei:
app/services/riegen.py
Datei:
app/services/auswertung.py
Dateien:
app/routes/auth.py- passendes Template in
app/templates/
Dateien:
app/routes/input.pyapp/templates/input.html
Die Datei enthaelt einen grossen Teil der Admin- und Eventlogik. Bei Aenderungen zuerst die konkrete Route suchen und dann die darunter aufgerufenen Hilfsfunktionen verfolgen.
Wenn unklar ist, wo Daten geschrieben oder gelesen werden, ist app/database/database.py meist die richtige Stelle.
Tabellenanpassungen werden nicht ueber ein externes Migrationstool verwaltet, sondern direkt in Database.
Bei Struktur-Aenderungen immer bestehende .db-Dateien mitdenken.
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
python main.pyOhne gesetztes ENV startet die App im Development-Modus.
Produktion wird ueber ENV=production aktiviert.
Dann greifen zusaetzliche Pruefungen, zum Beispiel fuer:
SECRET_KEYADMIN_PASSWORDSESSION_COOKIE_SECUREPREFERRED_URL_SCHEME
main.pyapp/__init__.pyapp/routes/auth.pyapp/routes/input.pyapp/services/app/database/database.py