Entry Points¶
Diese Seite dokumentiert alle Einstiegspunkte (Entry Points) des Vogelschlagmelders. Sie richtet sich an Entwickler*innen und Integrator*innen, die das System erweitern, anbinden oder debuggen möchten.
Die Anwendung ist ein FastAPI-basierter Webservice, der über Docker bereitgestellt wird. Die Entry Points gliedern sich in zwei Hauptkategorien:
Öffentliche Entry Points – ohne Authentifizierung erreichbar, für Endnutzer*innen und externe Systeme
Interne Entry Points – erfordern Authentifizierung, für Administration und Meldezentrale
Anwendungsstart¶
Der zentrale Einstiegspunkt der Anwendung ist app/main.py. Die Anwendung wird mit Uvicorn gestartet:
uvicorn main:app --host 0.0.0.0 --port 8000
Beim Start werden folgende Schritte ausgeführt:
FastAPI-App initialisieren (Titel: „Vogelschlagmelder“)
Statische Dateien und Jinja2-Templates registrieren
Alle Routen-Module einbinden
CSRF-Schutz- und Security-Header-Middleware aktivieren
Zugangsdaten validieren (
ADMIN_PASSWORD,MELDEZENTRALE_PASSWORD,CSRF_SECRET)Datenbank initialisieren und Standardeinstellungen anlegen
Vogelarten und Abdruckgrößen aus Seed-Daten befüllen
Docker¶
Die produktive Bereitstellung erfolgt über Docker Compose (docker-compose.yaml):
Eigenschaft |
Wert |
|---|---|
Basis-Image |
|
Port |
|
Benutzer |
|
Healthcheck |
|
Persistenz |
Volume |
Umgebungsvariablen¶
Variable |
Pflicht |
Standard |
Beschreibung |
|---|---|---|---|
|
ja |
|
Benutzername des System-Administrators |
|
ja |
– |
Passwort (mind. 8 Zeichen, nicht auf Schwachstellenliste) |
|
ja |
|
Benutzername der Meldezentrale |
|
ja |
– |
Passwort (mind. 8 Zeichen) |
|
ja |
– |
Zufälliger Schlüssel für CSRF-Tokens |
|
nein |
|
Aktiviert HTTPS-only-Cookies |
|
nein |
– |
SMTP-Server für E-Mail-Benachrichtigungen |
|
nein |
|
SMTP-Port |
|
nein |
– |
SMTP-Benutzername |
|
nein |
– |
SMTP-Passwort |
|
nein |
– |
Absender-Adresse |
|
nein |
|
TLS-Verschlüsselung verwenden |
|
nein |
– |
Von-Adresse in E-Mails |
|
nein |
– |
Von-Name in E-Mails |
Tipp
CSRF-Secret generieren: python3 -c "import secrets; print(secrets.token_hex(32))"
Öffentliche Entry Points¶
Alle hier aufgeführten Routen sind ohne Anmeldung erreichbar und bilden die Schnittstelle für Endnutzer*innen sowie externe Systeme.
Öffentliche Webseiten¶
Diese Routen liefern HTML-Seiten für die Bürger*innen-Interaktion aus.
Modul: app/src/routes_public.py
Route |
Methode |
Beschreibung |
|---|---|---|
|
GET |
Meldeformular mit Karte, Vogelartenliste und aktueller Uhrzeit |
|
POST |
Neue Vogelschlagmeldung absenden (inkl. Bildupload, Validierung, Benachrichtigungen) |
|
GET |
Optionale Infoseite (Weiterleitung auf |
|
GET |
Öffentliche Heatmap aller Vogelschläge (wenn aktiviert) |
|
GET |
Dynamisch generiertes CSS mit konfigurierten Theme-Farben |
Meldeformular-Felder (/meldung):
Koordinaten, Zeitstempel, Fensterabdruck (ja/nein/unbekannt), Vogelzustand (keiner/verletzt/tot), Fassadenrichtung, Adresse, Ortshinweise, Kontaktdaten, Vogelart, Abdruckgröße und bis zu 5 Fotos (max. 10 MB, HEIC/HEIF wird automatisch zu JPEG konvertiert).
Öffentliche REST-API¶
Die öffentliche API liefert Daten im JSON-Format und benötigt keine Authentifizierung.
Modul: app/src/routes_api.py
Route |
Methode |
Beschreibung |
Rückgabe |
|---|---|---|---|
|
GET |
Heatmap-Rasterdaten für die Gefahrenkarte (inkl. historischer Daten) |
|
|
GET |
Karten-Konfiguration |
|
Authentifizierte REST-API (API-Key)¶
Diese Endpunkte erfordern einen gültigen API-Schlüssel im Header X-Api-Key. API-Schlüssel werden in der Adminoberfläche verwaltet und in der Datenbank gespeichert.
Modul: app/src/routes_api.py
Route |
Methode |
Beschreibung |
Rückgabe |
|---|---|---|---|
|
GET |
Alle Meldungen des heutigen Tages |
|
|
GET |
Die zuletzt eingegangene Meldung |
Einzelnes Report-Objekt oder |
|
GET |
Umfassende Statistik (nach Jahr, Status, Fassadenrichtung, Monat) |
|
Report-JSON-Struktur:
{
"id": 42,
"lat": 50.927,
"lng": 11.586,
"timestamp": "2026-03-15T08:30:00",
"bird_status": "Vogel gefunden (tot)",
"has_window_imprint": true,
"bird_found": "dead",
"facade_orientation": "Süd",
"location_hint": "3. OG, Fenster zur Straße",
"email": "melder@example.org",
"phone": "+49 123 456789",
"image_paths": ["uploads/img_001.jpg"],
"duplicate": false,
"duplicate_reference_id": null,
"is_verified": true,
"bird_species": "Amsel",
"imprint_size": "Mittel (15–25 cm)"
}
Statische Dateien und Uploads¶
Route |
Methode |
Beschreibung |
|---|---|---|
|
GET |
Liefert hochgeladene Dateien aus; Logo und Favicon sind öffentlich, alle anderen erfordern Authentifizierung |
|
GET |
Öffentlich erreichbare CMS-Uploads (Bilder/Videos der Infoseite) |
|
GET |
Healthcheck-Endpunkt für Docker (gibt |
Interne Entry Points¶
Alle folgenden Routen erfordern eine gültige Sitzung (Cookie-basiert). Es gibt zwei Berechtigungsstufen:
Admin – Vollzugriff auf alle Einstellungen und die Meldezentrale
Meldezentrale – Zugriff auf Meldungsverwaltung und Datenexport
Authentifizierung¶
Modul: app/src/routes_auth.py
Route |
Methode |
Beschreibung |
|---|---|---|
|
GET |
Login-Seite mit CSRF-Token |
|
POST |
Login-Verarbeitung; setzt |
|
GET/POST |
Weiterleitung auf |
|
GET |
Admin-Abmeldung (Sitzung und Cookies löschen) |
|
GET/POST |
Weiterleitung auf |
|
GET |
Meldezentrale-Abmeldung |
Authentifizierungsarten:
Systemkonten – über Umgebungsvariablen konfiguriert (
ADMIN_USER/ADMIN_PASSWORD,MELDEZENTRALE_USER/MELDEZENTRALE_PASSWORD)Datenbankkonten – in der Adminoberfläche erstellt und verwaltet, Passwörter mit PBKDF2-SHA256 (120.000 Iterationen) gehasht
Sicherheitsmaßnahmen:
CSRF-Schutz (HMAC-SHA256, 1 h Gültigkeit)
Rate-Limiting: max. 5 Fehlversuche in 5 Minuten → 15 Minuten Sperrung
Sichere Cookies (
HttpOnly,SameSite=Strict,Secureim Produktionsmodus)IP-basiertes Login-Tracking
Admin – Dashboard und Konten¶
Modul: app/src/routes_admin.py
Route |
Methode |
Beschreibung |
|---|---|---|
|
GET |
Dashboard mit Statistik (Woche, Monat, Jahr, Gesamt) |
|
GET |
Benutzerkontenverwaltung |
|
POST |
Neues Benutzerkonto anlegen (Rolle: Admin oder Meldezentrale) |
|
POST |
Benutzerkonto bearbeiten |
|
POST |
Benutzerkonto löschen |
|
GET |
Element-/Matrix-Integrations-Einstellungen |
|
POST |
Test-Nachricht an konfiguriertem Element-Raum senden |
|
GET |
Matrix-Räume abrufen (AJAX) |
Admin – Erscheinungsbild und Anpassungen¶
Modul: app/src/routes_admin_settings.py
Route |
Methode |
Beschreibung |
|---|---|---|
|
GET |
Anpassungsseite anzeigen |
|
POST |
Logo hochladen (PNG/JPG/SVG/WebP, max. 2 MB) |
|
POST |
Logo entfernen |
|
POST |
Favicon hochladen und Tab-Titel setzen |
|
POST |
Favicon entfernen |
|
POST |
Browser-Tab-Titel ändern |
|
POST |
Organisationsname, Wirkungsbereich, Slogan |
|
POST |
Einleitungstext des Meldeformulars |
|
POST |
Unterüberschrift im Header-Bereich |
|
POST |
Hinweisbox (Titel und Inhalt) |
|
POST |
Zusätzliche Header-Buttons (Text + URLs) |
|
POST |
Farbschema (Primär, Dunkel, Hell, Akzent) |
|
POST |
Datenschutz- und Impressums-URLs |
Admin – Formular und Katalogdaten¶
Modul: app/src/routes_admin_settings.py
Route |
Methode |
Beschreibung |
|---|---|---|
|
GET |
Formularfeld-Konfiguration anzeigen |
|
POST |
Pflichtfelder-Einstellungen speichern (Name, Vorname, E-Mail, Telefon, Kontaktweg) |
|
GET |
Vogelarten-Katalog anzeigen |
|
POST |
Neue Vogelart anlegen |
|
POST |
Vogelart umbenennen |
|
POST |
Vogelart löschen |
|
GET |
Abdruckgrößen-Katalog anzeigen |
|
POST |
Neue Abdruckgröße anlegen |
|
POST |
Abdruckgröße bearbeiten |
|
POST |
Abdruckgröße löschen |
Admin – Karte und Gefahrenkarte¶
Modul: app/src/routes_admin_settings.py
Route |
Methode |
Beschreibung |
|---|---|---|
|
GET |
Karten-Konfiguration anzeigen |
|
POST |
Kartenmittelpunkt (Lat/Lng), Zoom-Stufe und Radius speichern |
|
GET |
Heatmap-Konfiguration anzeigen |
|
POST |
Heatmap-Einstellungen speichern (Sichtbarkeit, Rastergröße, Schwellwerte, Farben) |
Admin – Historische Daten¶
Modul: app/src/routes_admin_data.py
Route |
Methode |
Beschreibung |
|---|---|---|
|
GET |
Historische Daten mit Import-/Exportfunktion anzeigen |
|
POST |
Historische Daten in Statistik einbeziehen (ja/nein) |
|
POST |
CSV-Import (Spalten: Latitude, Longitude, Straße, Hausnummer, PLZ, Stadt, Hinweise, Anzahl Meldungen, Seite der Kollision) |
|
POST |
Alle historischen Datensätze löschen |
|
POST |
Einzelnen historischen Datensatz manuell anlegen |
|
GET |
Bearbeitungsformular für historischen Datensatz |
|
POST |
Historischen Datensatz aktualisieren |
|
POST |
Einzelnen historischen Datensatz löschen |
Admin – Widgets, Infoseite und Einstellungssicherung¶
Modul: app/src/routes_admin_data.py
Route |
Methode |
Beschreibung |
|---|---|---|
|
GET |
Widget-Konfiguration (Platzhalter) |
|
GET |
Infoseiten-Editor anzeigen |
|
POST |
Infoseite speichern (JSON-Blöcke: Text, Bild, Video, Abstandshalter) |
|
GET |
Alle Einstellungen als ZIP-Backup exportieren |
|
POST |
Einstellungen aus ZIP-Backup importieren |
Meldezentrale – Meldungsverwaltung¶
Modul: app/src/routes_meldezentrale.py
Route |
Methode |
Beschreibung |
|---|---|---|
|
GET |
Weiterleitung auf |
|
GET |
Meldungsliste mit erweiterter Filter- und Paginierungsfunktion |
|
GET |
Detailansicht einer Meldung |
|
POST |
Meldung bearbeiten (Ort, Kontaktdaten, Status) |
|
POST |
Meldung als geprüft markieren |
|
POST |
Meldung als ungenügend markieren |
|
POST |
Meldung als Duplikat markieren |
|
POST |
Meldung löschen |
|
POST |
Einzelnes Bild einer Meldung löschen |
Filterparameter (Query-String):
Parameter |
Beschreibung |
|---|---|
|
Seitenzahl und Elemente pro Seite (10, 25, 50, 100) |
|
Duplikate ausblenden |
|
Ungenügende Meldungen ausblenden |
|
Bereits geprüfte Meldungen ausblenden |
|
Zeitraumfilter (ISO-8601) |
|
Volltextsuche (Name, E-Mail, Telefon, Adresse, Vogelart …) |
|
Geografische Begrenzung |
|
Gespeicherten Filter laden |
Meldezentrale – Gespeicherte Filter¶
Modul: app/src/routes_meldezentrale.py
Route |
Methode |
Beschreibung |
|---|---|---|
|
POST |
Aktuelle Filtereinstellungen mit Name speichern |
|
POST |
Gespeicherten Filter löschen |
|
GET |
Gespeicherten Filter laden (Weiterleitung mit angewandtem Filter) |
Meldezentrale – Datenexport und Statistik¶
Modul: app/src/routes_export.py
Route |
Methode |
Beschreibung |
Format |
|---|---|---|---|
|
GET |
Exportseite mit Filteroptionen |
HTML |
|
GET |
Statistikseite mit Diagrammen und Tabellen |
HTML |
|
GET/POST |
Gefilterte Meldungen als CSV exportieren |
CSV (Semikolon-getrennt) |
|
GET |
Bilder gefilterter Meldungen als ZIP exportieren |
ZIP |
|
GET |
Meldungen innerhalb eines Kartenausschnitts als CSV |
CSV |
|
GET |
Bilder eines Kartenausschnitts als ZIP |
ZIP |
CSV-Spalten: ID, Datum, Uhrzeit, Latitude, Longitude, Straße, Hausnummer, PLZ, Stadt, Vogelzustand, Vogelart, Abdruckgröße, Fassadenrichtung, Hinweise zum Ort, Name, Vorname, E-Mail, Telefon, Bilder, Duplikat, Referenz-ID, Geprüft.
Hintergrunddienste¶
Diese Komponenten sind keine HTTP-Routen, sondern werden intern beim Absenden einer Meldung (POST /meldung) ausgelöst.
E-Mail-Benachrichtigungen¶
Modul: app/src/notifications.py
Beim Eingang einer neuen Meldung wird eine E-Mail an alle in AdminSettings.notification_emails hinterlegten Adressen gesendet. Die Nachricht enthält einen HTML-formatierten Bericht mit Link zur OpenStreetMap-Position.
Voraussetzung: Gültige SMTP-Konfiguration über Umgebungsvariablen.
Element-/Matrix-Benachrichtigungen¶
Module: app/src/notifications.py, app/src/element_connector.py
Wenn die Element-Integration aktiviert ist (ElementSettings.is_enabled), wird bei jeder neuen Meldung eine HTML-formatierte Nachricht an den konfigurierten Matrix-Raum gesendet.
Funktionen des Element-Connectors:
Funktion |
Beschreibung |
|---|---|
|
Beitretene Matrix-Räume abrufen |
|
Text-/HTML-Nachricht an einen Raum senden |
|
Testbenachrichtigung senden |
|
Prüfen, ob die Integration vollständig konfiguriert ist |
Datenbank¶
Datenbanksystem: SQLite
Pfad: /app/data/vogelschlagmelder.db
Tabellen¶
Tabelle |
Beschreibung |
|---|---|
|
Vogelschlagmeldungen (Koordinaten, Zeitstempel, Vogelstatus, Kontaktdaten, Bilder, Duplikat-/Prüfstatus) |
|
Importierte historische Daten (Standort, Anzahl Meldungen) |
|
Website-Konfiguration (Logo, Favicon, Farben, Pflichtfelder, Funktionsschalter) |
|
Kartenmittelpunkt, Zoom-Stufe, maximaler Radius |
|
Gefahrenkarte (Sichtbarkeit, Rastergröße, Schwellwerte, Farbwerte) |
|
Einstellung, ob historische Daten in Statistiken einfließen |
|
Admin-Konfiguration (Benachrichtigungs-E-Mails als JSON) |
|
Matrix-Integration (Homeserver-URL, Access-Token, Raum-ID, Aktivierungsstatus) |
|
Datenbankbasierte Benutzerkonten (Benutzername, Passwort-Hash, Rollen) |
|
Vogelarten-Katalog |
|
Abdruckgrößen-Katalog (Name, Sortierung) |
|
REST-API-Schlüssel (Schlüssel, Name, Aktivierungsstatus) |
|
Gespeicherte Tabellenfilter (Name, Parameter als JSON) |
Initialisierung beim Start¶
Beim Anwendungsstart werden automatisch folgende Schritte ausgeführt:
init_database()– Tabellen erstellen, falls nicht vorhandenensure_report_schema()– Fehlende Spalten nachträglich hinzufügen (Migrationen)ensure_bird_species_defaults()– Vogelarten ausbird_list_germany.txteinspielenensure_imprint_size_defaults()– Standard-Abdruckgrößen anlegen
Sicherheitsmechanismen¶
Modul: app/src/security.py
Mechanismus |
Beschreibung |
|---|---|
CSRF-Schutz |
Token-Generierung und -Validierung mit HMAC-SHA256 (1 h Gültigkeit). Origin/Referer-Prüfung auf allen schreibenden Endpunkten (außer |
Rate-Limiting |
Max. 5 fehlgeschlagene Login-Versuche pro IP in 5 Minuten → 15 Minuten Sperre. |
Datei-Upload-Validierung |
Prüfung von Dateityp (Magic Bytes) und Dateigröße. Erlaubt: PNG, JPG, GIF, WebP, HEIC. |
HTTP-Security-Header |
|
HTML-Sanitisierung |
Entfernung potenziell schädlicher Inhalte in Benutzereingaben über Jinja2-Filter |
Passwort-Hashing |
PBKDF2-SHA256 mit 120.000 Iterationen für Datenbankkonten. |
Übersicht aller Entry Points¶
Kategorie |
Anzahl |
Beispiele |
|---|---|---|
Öffentliche Webseiten |
5 |
|
Öffentliche API |
2 |
|
API mit Schlüssel |
3 |
|
Authentifizierung |
8 |
|
Admin-Routen |
~50 |
|
Meldezentrale-Routen |
~15 |
|
Export-Routen |
6 |
|
Hintergrunddienste |
2 |
E-Mail-Benachrichtigungen, Element-/Matrix-Benachrichtigungen |
Gesamt HTTP-Endpunkte |
~90 |