agentic.email/backend/app/schemas.py
2026-10-04 15:35:17 +05:30

234 lines
5.5 KiB
Python

from datetime import datetime, timezone
from datetime import date
from typing import Literal
from uuid import UUID
from pydantic import BaseModel, ConfigDict, EmailStr, Field
class AccountRegister(BaseModel):
account_type: Literal["individual", "company"]
email_name: str = Field(
min_length=1,
max_length=64,
pattern=r"^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,62}[A-Za-z0-9])?$",
)
company_domain: str | None = Field(default=None, max_length=253)
first_name: str = Field(min_length=1, max_length=80)
last_name: str = Field(min_length=1, max_length=80)
date_of_birth: date
phone_number: str = Field(
min_length=7,
max_length=24,
pattern=r"^\+?[0-9][0-9 ()-]{5,22}[0-9]$",
)
password: str = Field(min_length=8, max_length=128)
class AccountRead(BaseModel):
id: UUID
account_type: str
email: EmailStr
first_name: str
last_name: str
date_of_birth: date
phone_number: str
company_domain: str | None
is_domain_owner: bool = False
created_at: datetime
model_config = ConfigDict(from_attributes=True)
class LoginRequest(BaseModel):
email: EmailStr
password: str = Field(min_length=1, max_length=128)
class AuthResponse(BaseModel):
access_token: str
token_type: Literal["bearer"] = "bearer"
account: AccountRead
class EmailCreate(BaseModel):
recipients: list[EmailStr] = Field(min_length=1)
cc: list[EmailStr] = Field(default_factory=list)
bcc: list[EmailStr] = Field(default_factory=list)
subject: str = Field(default="", max_length=998, pattern=r"^[^\r\n]*$")
body_text: str = ""
body_html: str | None = None
class EmailRead(EmailCreate):
id: str
sender: EmailStr
status: str
created_at: datetime
class MailAddress(BaseModel):
name: str
address: str
class AttachmentRead(BaseModel):
filename: str
content_type: str
size: int
content_id: str | None = None
disposition: str = "attachment"
class MessageSummary(BaseModel):
id: str
mailbox: Literal["inbox", "sent", "trash"]
direction: Literal["inbound", "outbound"]
sender: MailAddress
recipients: list[MailAddress]
subject: str
snippet: str
status: str
created_at: datetime
is_read: bool
is_starred: bool = False
trashed_at: datetime | None = None
attachments: list[AttachmentRead] = Field(default_factory=list)
class MessageRead(MessageSummary):
cc: list[MailAddress] = Field(default_factory=list)
bcc: list[MailAddress] = Field(default_factory=list)
reply_to: list[MailAddress] = Field(default_factory=list)
body_text: str = ""
body_html: str | None = None
message_id: str | None = None
class MessageReadState(BaseModel):
is_read: bool
class MessageStarState(BaseModel):
is_starred: bool
class StickyNoteCreate(BaseModel):
title: str = Field(min_length=1, max_length=120)
body: str = Field(default="", max_length=2000)
tags: list[str] = Field(default_factory=list, max_length=5)
color: Literal["yellow", "green", "blue", "pink"] = "yellow"
class StickyNoteUpdate(BaseModel):
title: str | None = Field(default=None, min_length=1, max_length=120)
body: str | None = Field(default=None, max_length=2000)
tags: list[str] | None = Field(default=None, max_length=5)
color: Literal["yellow", "green", "blue", "pink"] | None = None
class StickyNoteRead(StickyNoteCreate):
id: str
created_at: datetime
updated_at: datetime
class MessagePage(BaseModel):
items: list[MessageSummary]
next_cursor: str | None = None
class DomainCreate(BaseModel):
domain_name: str = Field(min_length=3, max_length=253)
account_id: UUID | None = None
class DomainNameCreate(BaseModel):
domain_name: str = Field(min_length=3, max_length=253)
class DnsRecordRead(BaseModel):
id: UUID
record_type: str
host: str
value: str
purpose: str
ttl: int
model_config = ConfigDict(from_attributes=True)
class DnsVerificationCheck(BaseModel):
purpose: str
verified: bool
message: str
class DnsVerificationResponse(BaseModel):
domain: str
status: str
verified: bool
checks: list[DnsVerificationCheck]
class MailDomainRead(BaseModel):
id: UUID
domain_name: str
domain_type: str
account_id: UUID | None
mail_host: str
dkim_selector: str
status: str
created_at: datetime
dns_records: list[DnsRecordRead] = []
model_config = ConfigDict(from_attributes=True)
class SmtpCredentialCreate(BaseModel):
label: str = Field(default="default", min_length=1, max_length=120)
class SmtpCredentialRead(BaseModel):
id: UUID
username: str
label: str
is_active: bool
created_at: datetime
model_config = ConfigDict(from_attributes=True)
class SmtpCredentialCreated(SmtpCredentialRead):
password: str
smtp_host: str
smtp_port: int
use_tls: bool
class DnsSetupRequest(BaseModel):
domain: str = Field(min_length=3, max_length=253)
mail_server_ip: str = Field(min_length=3, max_length=45)
class DnsSetupRecord(BaseModel):
record_type: str
host: str
value: str
purpose: str
ttl: int
priority: int | None = None
class DnsSetupResponse(BaseModel):
domain: str
mail_host: str
app_public_host: str
mail_server_ip: str
is_platform_domain: bool
sections: dict[str, list[DnsSetupRecord]]
notes: list[str] = Field(default_factory=list)
def utc_now() -> datetime:
return datetime.now(timezone.utc)