15 pyflakes-Warnings entfernt: - src/audit.py: HTTPException (in router import statt helper, war hier ungenutzt) - src/routers/auth.py: status (FastAPI-status ungenutzt) - src/routers/audit.py: HTTPException (ungenutzt) - src/routers/users.py: MAGIC_LINK_EXPIRE_MINUTES (ungenutzt) - src/routers/sources.py: row_to_dict, _extract_domain, _detect_category, urlparse, status (alle ungenutzt - status.HTTP_* wird nirgendwo aufgerufen) - src/routers/sources.py: 2x f-string ohne Placeholder (URL aktualisiert, Verbindung fehlgeschlagen) zu normalen Strings - src/routers/sources.py: except httpx.ConnectError as e -> e ungenutzt, weg - src/database.py: os ungenutzt - src/models.py: EmailStr ungenutzt Audit-Coverage geprueft: alle write-Endpoints in users.py rufen _toggle_field() auf, das die log_action-Aufrufe macht. Keine Audit-Luecken. Alle anderen Routers (organizations/licenses/dashboard/token_usage) hatten bereits saubere Audit-Coverage. Mojibake-Diagnose ueber alle src/*.py: 0 Treffer.
97 Zeilen
2.5 KiB
Python
97 Zeilen
2.5 KiB
Python
"""Pydantic Models für das Verwaltungsportal."""
|
|
from pydantic import BaseModel, Field
|
|
from typing import Optional
|
|
|
|
|
|
class MagicLinkRequest(BaseModel):
|
|
email: str = Field(min_length=3, max_length=200)
|
|
|
|
|
|
class MagicLinkResponse(BaseModel):
|
|
message: str
|
|
|
|
|
|
class VerifyTokenRequest(BaseModel):
|
|
token: str = Field(min_length=10, max_length=200)
|
|
|
|
|
|
class TokenResponse(BaseModel):
|
|
access_token: str
|
|
token_type: str = "bearer"
|
|
username: str
|
|
email: str = ""
|
|
|
|
|
|
class OrgCreate(BaseModel):
|
|
name: str = Field(min_length=1, max_length=200)
|
|
slug: str = Field(min_length=1, max_length=100, pattern="^[a-z0-9-]+$")
|
|
|
|
|
|
class OrgUpdate(BaseModel):
|
|
name: Optional[str] = Field(default=None, max_length=200)
|
|
is_active: Optional[bool] = None
|
|
|
|
|
|
class OrgResponse(BaseModel):
|
|
id: int
|
|
name: str
|
|
slug: str
|
|
is_active: bool
|
|
user_count: int = 0
|
|
license_status: str = ""
|
|
license_type: str = ""
|
|
created_at: str
|
|
globe_access: bool = False
|
|
network_access: bool = False
|
|
|
|
|
|
class LicenseCreate(BaseModel):
|
|
organization_id: int
|
|
license_type: str = Field(pattern="^(trial|annual|permanent)$")
|
|
max_users: int = Field(default=5, ge=1, le=1000)
|
|
duration_days: Optional[int] = Field(default=None, ge=1, le=3650)
|
|
token_budget_usd: Optional[float] = None
|
|
credits_total: Optional[int] = None
|
|
cost_per_credit: Optional[float] = None
|
|
budget_warning_percent: Optional[int] = Field(default=80, ge=1, le=100)
|
|
unlimited_budget: bool = False
|
|
|
|
|
|
class LicenseResponse(BaseModel):
|
|
id: int
|
|
organization_id: int
|
|
license_type: str
|
|
max_users: int
|
|
valid_from: str
|
|
valid_until: Optional[str]
|
|
status: str
|
|
notes: Optional[str]
|
|
token_budget_usd: Optional[float] = None
|
|
credits_total: Optional[int] = None
|
|
credits_used: Optional[float] = None
|
|
cost_per_credit: Optional[float] = None
|
|
budget_warning_percent: Optional[int] = None
|
|
unlimited_budget: bool = False
|
|
created_at: str
|
|
globe_access: bool = False
|
|
network_access: bool = False
|
|
|
|
|
|
class UserCreate(BaseModel):
|
|
email: str = Field(min_length=3, max_length=200)
|
|
username: Optional[str] = Field(default=None, max_length=100)
|
|
role: str = Field(default="member", pattern="^(org_admin|member)$")
|
|
|
|
|
|
class UserResponse(BaseModel):
|
|
id: int
|
|
email: str
|
|
username: str
|
|
organization_id: int
|
|
role: str
|
|
is_active: bool
|
|
last_login_at: Optional[str]
|
|
created_at: str
|
|
globe_access: bool = False
|
|
network_access: bool = False
|