feat: Submission-Pydantic-Modell mit Validierung
This commit is contained in:
@@ -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")
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user