"""Shared API response models (SPEC §9.1).""" from __future__ import annotations import datetime as dt import uuid from pydantic import BaseModel class Address(BaseModel): name: str = "" email: str = "" class ThreadSummary(BaseModel): id: uuid.UUID subject: str snippet: str participants: list[Address] account_ids: list[uuid.UUID] message_count: int unread_count: int has_attachments: bool pinned: bool last_message_at: dt.datetime class ThreadListOut(BaseModel): threads: list[ThreadSummary] cursor: str | None = None total: int = 0 class AttachmentOut(BaseModel): id: uuid.UUID filename: str mime_type: str size_bytes: int class MessageEnvelope(BaseModel): id: uuid.UUID account_id: uuid.UUID mailbox_id: uuid.UUID thread_id: uuid.UUID | None subject: str from_addr: list[Address] to_addr: list[Address] cc_addr: list[Address] bcc_addr: list[Address] date: dt.datetime flags: list[str] is_unread: bool is_starred: bool has_attachments: bool has_remote_images: bool # The sender is on the user's trusted list, so remote images load without a prompt. images_allowed: bool = False size_bytes: int snippet: str # Other accounts this same delivery also landed in (collapsed duplicates). also_in_account_ids: list[uuid.UUID] = [] class ThreadDetail(BaseModel): id: uuid.UUID subject: str order: str # "asc" | "desc" pinned: bool messages: list[MessageEnvelope] # always ASC (SPEC §9.4) class FlagChangeRequest(BaseModel): add: list[str] = [] remove: list[str] = [] class MarkReadRequest(BaseModel): view: str = "unified" # unified | folder: | account: class MoveRequest(BaseModel): mailbox_id: uuid.UUID class AccountOut(BaseModel): id: uuid.UUID email: str display_name: str color: str state: str signature: str = "" sync_window: str = "all" backfill_total: int = 0 backfill_done: int = 0 class SearchThreadHit(BaseModel): thread: ThreadSummary highlights: dict[str, str] class SearchOut(BaseModel): threads: list[SearchThreadHit] cursor: str | None = None