feat: Submission-Pydantic-Modell mit Validierung

This commit is contained in:
Hermes Agent
2026-06-22 06:29:28 +02:00
parent ac7aa0197b
commit 204da375c5
7 changed files with 285 additions and 0 deletions
View File
+14
View File
@@ -0,0 +1,14 @@
from datetime import datetime
from pydantic import BaseModel, Field
class Submission(BaseModel):
"""Eine Community-Einreichung (WhatsApp/Telegram)."""
message_id: str = Field(..., description="Eindeutige Nachrichten-ID")
plattform: str = Field(..., description="whatsapp oder telegram")
absender: str = Field(..., description="Absender-ID oder Telefonnummer")
text: str = Field(..., min_length=1, max_length=5000, description="Nachrichtentext")
zeitstempel: datetime = Field(default_factory=datetime.now, description="Eingangszeitpunkt")
status: str = Field(default="neu", description="neu, in_bearbeitung, erledigt, fehler")
View File
+98
View File
@@ -0,0 +1,98 @@
"""Input-Validatoren für das BSN-Livesystem."""
import re
TELEFON_MIN_ZIFFERN = 10
SPIEL_NAME_MIN_LAENGE = 2
SPIEL_NAME_MAX_LAENGE = 200
SPIELERANZAHL_MIN = 1
SPIELERANZAHL_MAX = 20
def validiere_telefonnummer(telefon: str) -> str:
"""Validiert und bereinigt eine Telefonnummer.
Entfernt alle Zeichen außer '+' und Ziffern. Konvertiert führende '00'
zu '+'. Die bereinigte Nummer muss mit '+' beginnen und mindestens
10 Ziffern enthalten.
Args:
telefon: Die zu validierende Telefonnummer als String.
Returns:
Die bereinigte Telefonnummer.
Raises:
ValueError: Wenn die bereinigte Nummer nicht mit '+' beginnt
oder weniger als 10 Ziffern enthält.
"""
# Nur + und Ziffern behalten
bereinigt = re.sub(r"[^+\d]", "", telefon)
# "00" durch "+" ersetzen (nur am Anfang)
if bereinigt.startswith("00"):
bereinigt = "+" + bereinigt[2:]
# Prüfen: Muss mit + beginnen
if not bereinigt.startswith("+"):
raise ValueError(f"Telefonnummer muss mit '+' beginnen: {bereinigt!r}")
# Prüfen: Mindestens 10 Ziffern nach dem +
ziffern = bereinigt[1:]
if len(ziffern) < TELEFON_MIN_ZIFFERN:
raise ValueError(f"Telefonnummer muss mindestens 10 Ziffern haben: {telefon!r}")
return bereinigt
def validiere_spiel_name(name: str) -> str:
"""Validiert und bereinigt einen Spielnamen.
Entfernt HTML-Tags und umgebenden Whitespace. Der bereinigte Name
muss zwischen 2 und 200 Zeichen lang sein.
Args:
name: Der zu validierende Spielname als String.
Returns:
Der bereinigte Spielname.
Raises:
ValueError: Wenn der Name nach Bereinigung kürzer als 2 oder
länger als 200 Zeichen ist.
"""
# HTML-Tags entfernen
bereinigt = re.sub(r"<[^>]*>", "", name)
# Whitespace strippen
bereinigt = bereinigt.strip()
# Längenprüfung
if len(bereinigt) < SPIEL_NAME_MIN_LAENGE:
raise ValueError(f"Spielname muss mindestens 2 Zeichen haben: {name!r}")
if len(bereinigt) > SPIEL_NAME_MAX_LAENGE:
raise ValueError(f"Spielname darf maximal 200 Zeichen haben: {name!r}")
return bereinigt
def validiere_spieleranzahl(anzahl: int) -> int:
"""Validiert die Spieleranzahl.
Die Anzahl muss zwischen 1 und 20 liegen.
Args:
anzahl: Die zu validierende Spieleranzahl.
Returns:
Die unveränderte Spieleranzahl, wenn gültig.
Raises:
ValueError: Wenn die Anzahl kleiner als 1 oder größer als 20 ist.
"""
if anzahl < SPIELERANZAHL_MIN:
raise ValueError(f"Spieleranzahl muss mindestens 1 sein: {anzahl}")
if anzahl > SPIELERANZAHL_MAX:
raise ValueError(f"Spieleranzahl darf maximal 20 sein: {anzahl}")
return anzahl