Files
webmail-client/backend/app/accounts/schemas.py
T

106 lines
2.4 KiB
Python
Raw Normal View History

2026-07-17 23:20:34 +02:00
"""Request/response models for the accounts API (SPEC §9.1)."""
from __future__ import annotations
import uuid
from typing import Literal
2026-07-17 23:20:34 +02:00
from pydantic import BaseModel, Field
# How much history to import at account setup (SPEC §12 M2).
SyncWindow = Literal["all", "3months", "new"]
2026-07-17 23:20:34 +02:00
class ServerConfigIn(BaseModel):
host: str
port: int = Field(ge=1, le=65535)
tls: str = "ssl" # ssl | starttls
auth: str = "password" # password | oauth2
class DiscoverRequest(BaseModel):
email: str
class HelpBlockOut(BaseModel):
help_id: str
deep_link: str
app_name_hint: str = ""
steps: list[str] = []
docs_url: str = ""
setup_link: str = ""
button_after_step: int = 0
2026-07-17 23:20:34 +02:00
class CandidateOut(BaseModel):
imap: ServerConfigIn
smtp: ServerConfigIn
source: str
oauth_provider: str | None = None
auth_strategy: list[str] = ["password"]
help: HelpBlockOut | None = None
2026-07-17 23:20:34 +02:00
class DiscoveryStepOut(BaseModel):
method: str
status: str
detail: str = ""
class DiscoverResponse(BaseModel):
candidates: list[CandidateOut]
steps: list[DiscoveryStepOut]
# Whether the wizard may offer the Google OAuth fallback (SPEC §6.2.1).
google_oauth_enabled: bool = False
2026-07-17 23:20:34 +02:00
class TestRequest(BaseModel):
imap: ServerConfigIn
smtp: ServerConfigIn
email: str
username: str | None = None # defaults to the email address
password: str = Field(min_length=1)
class TestResponse(BaseModel):
ok: bool = True
class CreateAccountRequest(BaseModel):
email: str
display_name: str = ""
color: str = "#888888"
imap: ServerConfigIn
smtp: ServerConfigIn
username: str | None = None
password: str = Field(min_length=1)
sync_window: SyncWindow = "all"
sync_spam: bool = False
2026-07-17 23:20:34 +02:00
class UpdateAccountRequest(BaseModel):
display_name: str | None = None
color: str | None = None
signature: str | None = None
sync_window: SyncWindow | None = None
# Connection/credential changes require the password (re-validated + re-encrypted).
imap: ServerConfigIn | None = None
smtp: ServerConfigIn | None = None
password: str | None = None
2026-07-17 23:20:34 +02:00
class AccountDetailOut(BaseModel):
id: uuid.UUID
email: str
display_name: str
color: str
state: str
state_detail: str
signature: str
sync_window: str
backfill_total: int
backfill_done: int
2026-07-17 23:20:34 +02:00
imap_config: dict[str, object]
smtp_config: dict[str, object]
kind: str = "external"