from typing import Literal from pydantic import BaseModel, EmailStr, Field, field_validator, model_validator SettingsSource = Literal["database", "environment", "missing"] def normalize_text(value: object) -> str: if value is None: return "" return str(value).strip() class SmtpSettingsResponse(BaseModel): host: str = "" port: int = 587 username: str = "" password_is_set: bool = False from_email: str = "" from_name: str = "Funktechnik Schubert" use_tls: bool = True enabled: bool = False source: SettingsSource class SmtpSettingsUpdate(BaseModel): host: str = Field(default="", max_length=255) port: int = Field(default=587, ge=1, le=65535) username: str = Field(default="", max_length=255) password: str | None = Field(default=None, max_length=1000) from_email: str = Field(default="", max_length=255) from_name: str = Field(default="Funktechnik Schubert", max_length=255) use_tls: bool = True enabled: bool = False @field_validator("host", "username", "password", "from_email", "from_name", mode="before") @classmethod def normalize_strings(cls, value: object) -> str: return normalize_text(value) @model_validator(mode="after") def validate_enabled_configuration(self): if self.enabled and (not self.host or not self.from_email): raise ValueError("SMTP Host und Absenderadresse sind erforderlich, wenn SMTP aktiviert ist") return self class SmtpTestRequest(BaseModel): recipient: EmailStr class SmtpTestResponse(BaseModel): success: bool message: str source: SettingsSource class PublicLinksSettingsResponse(BaseModel): repair_status_base_url: str = "" source: SettingsSource class PublicLinksSettingsUpdate(BaseModel): repair_status_base_url: str = Field(default="", max_length=500) @field_validator("repair_status_base_url", mode="before") @classmethod def normalize_url(cls, value: object) -> str: return normalize_text(value).rstrip("/")