mirror of
https://github.com/idrainformatica/PecFlow.git
synced 2026-06-16 20:55:41 +02:00
111 lines
3.1 KiB
Python
111 lines
3.1 KiB
Python
"""
|
|
Schemi Pydantic per Message, Attachment e operazioni correlate.
|
|
"""
|
|
|
|
import uuid
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from pydantic import BaseModel, model_validator
|
|
|
|
from app.schemas.label import LabelResponse
|
|
|
|
|
|
class AttachmentResponse(BaseModel):
|
|
id: uuid.UUID
|
|
message_id: uuid.UUID
|
|
filename: str
|
|
content_type: Optional[str] = None
|
|
size_bytes: Optional[int] = None
|
|
storage_path: str
|
|
checksum_sha256: Optional[str] = None
|
|
created_at: datetime
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class MessageResponse(BaseModel):
|
|
id: uuid.UUID
|
|
tenant_id: uuid.UUID
|
|
mailbox_id: uuid.UUID
|
|
message_id_header: Optional[str] = None
|
|
imap_uid: Optional[int] = None
|
|
imap_folder: str
|
|
direction: str
|
|
pec_type: str
|
|
state: str
|
|
subject: Optional[str] = None
|
|
from_address: Optional[str] = None
|
|
to_addresses: list[str] = []
|
|
cc_addresses: list[str] = []
|
|
sent_at: Optional[datetime] = None
|
|
received_at: Optional[datetime] = None
|
|
size_bytes: Optional[int] = None
|
|
body_text: Optional[str] = None
|
|
body_html: Optional[str] = None
|
|
has_attachments: bool = False
|
|
parent_message_id: Optional[uuid.UUID] = None
|
|
is_read: bool = False
|
|
is_starred: bool = False
|
|
is_archived: bool = False
|
|
archived_at: Optional[datetime] = None
|
|
is_trashed: bool = False
|
|
trashed_at: Optional[datetime] = None
|
|
is_pending_conservation: bool = False
|
|
pending_conservation_at: Optional[datetime] = None
|
|
is_conserved: bool = False
|
|
conserved_at: Optional[datetime] = None
|
|
raw_eml_path: Optional[str] = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
labels: list[LabelResponse] = []
|
|
|
|
@model_validator(mode="before")
|
|
@classmethod
|
|
def coerce_arrays(cls, data: object) -> object:
|
|
"""Normalizza i campi array a liste vuote se None (da ORM)."""
|
|
if hasattr(data, "__dict__"):
|
|
# ORM object
|
|
for field in ("to_addresses", "cc_addresses"):
|
|
val = getattr(data, field, None)
|
|
if val is None:
|
|
object.__setattr__(data, field, [])
|
|
elif isinstance(data, dict):
|
|
for field in ("to_addresses", "cc_addresses"):
|
|
if data.get(field) is None:
|
|
data[field] = []
|
|
return data
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class MessageListResponse(BaseModel):
|
|
items: list[MessageResponse]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
|
|
|
|
class MessageUpdateRequest(BaseModel):
|
|
is_read: Optional[bool] = None
|
|
is_starred: Optional[bool] = None
|
|
is_archived: Optional[bool] = None
|
|
is_trashed: Optional[bool] = None
|
|
is_pending_conservation: Optional[bool] = None
|
|
is_conserved: Optional[bool] = None
|
|
|
|
|
|
class MessageBulkUpdateRequest(BaseModel):
|
|
ids: list[uuid.UUID]
|
|
is_read: Optional[bool] = None
|
|
is_starred: Optional[bool] = None
|
|
is_archived: Optional[bool] = None
|
|
is_trashed: Optional[bool] = None
|
|
is_pending_conservation: Optional[bool] = None
|
|
is_conserved: Optional[bool] = None
|
|
|
|
|
|
class MessageBulkUpdateResponse(BaseModel):
|
|
updated: int
|
|
items: list[MessageResponse]
|