"""Compose/draft/send request & response models (SPEC ยง9.1).""" from __future__ import annotations import uuid from pydantic import BaseModel class DraftPayload(BaseModel): to: list[str] = [] cc: list[str] = [] bcc: list[str] = [] subject: str = "" html: str = "" text: str = "" attachment_ids: list[uuid.UUID] = [] class DraftIn(BaseModel): account_id: uuid.UUID thread_id: uuid.UUID | None = None reply_to_message_id: uuid.UUID | None = None kind: str = "new" # reply | reply_all | forward | new payload: DraftPayload class DraftOut(BaseModel): id: uuid.UUID account_id: uuid.UUID thread_id: uuid.UUID | None reply_to_message_id: uuid.UUID | None kind: str payload: dict[str, object] updated_at: str class RemoteDraftOut(BaseModel): """A draft found in the account's IMAP Drafts folder (created on another client).""" message_id: uuid.UUID account_id: uuid.UUID imap_uid: int subject: str to: list[str] cc: list[str] bcc: list[str] snippet: str updated_at: str class SendRequest(BaseModel): draft_id: uuid.UUID class SendResponse(BaseModel): outbox_id: uuid.UUID undo_until: str # The same deadline as seconds from now: the browser counts down from this, # since its clock may be seconds off the server's. undo_seconds: float class OutboxStateOut(BaseModel): outbox_id: uuid.UUID state: str class OutboxItemOut(BaseModel): """A send waiting in the Scheduled folder: being retried, or failed for good.""" outbox_id: uuid.UUID draft_id: uuid.UUID account_id: uuid.UUID state: str # "retrying" | "failed" attempts: int error: str | None next_attempt_at: str | None retry_until: str | None sent_at: str # when Send was pressed (the end of the undo window) to: list[str] subject: str preview: str