from pydantic import BaseModel, Field, field_validator from typing import Optional, List from uuid import UUID from datetime import datetime VALID_STATUSES = {"open", "waiting_on_customer", "waiting_on_staff", "resolved", "closed"} VALID_PRIORITIES = {"low", "medium", "high", "urgent"} VALID_OPENED_VIA = {"app", "email", "phone", "staff"} VALID_SENDERS = {"staff", "customer"} class TicketCreate(BaseModel): customer_id: str customer_name: Optional[str] = None subject: str = Field(..., max_length=500) device_id: Optional[str] = None device_serial: Optional[str] = None opened_via: Optional[str] = None priority: Optional[str] = None @field_validator("priority") @classmethod def check_priority(cls, v): if v is not None and v not in VALID_PRIORITIES: raise ValueError(f"priority must be one of {VALID_PRIORITIES}") return v class TicketUpdate(BaseModel): status: Optional[str] = None priority: Optional[str] = None device_id: Optional[str] = None device_serial: Optional[str] = None @field_validator("status") @classmethod def check_status(cls, v): if v is not None and v not in VALID_STATUSES: raise ValueError(f"status must be one of {VALID_STATUSES}") return v class MessageCreate(BaseModel): sender_type: str sender_id: str sender_name: Optional[str] = None body: str is_internal: bool = False @field_validator("sender_type") @classmethod def check_sender_type(cls, v): if v not in VALID_SENDERS: raise ValueError(f"sender_type must be one of {VALID_SENDERS}") return v class EscalateIn(BaseModel): entry_id: UUID class MessageOut(BaseModel): id: UUID sender_type: str sender_id: str sender_name: Optional[str] body: str is_internal: bool created_at: datetime model_config = {"from_attributes": True} class TicketOut(BaseModel): id: UUID customer_id: str customer_name: Optional[str] device_id: Optional[str] device_serial: Optional[str] subject: str status: str priority: Optional[str] opened_via: Optional[str] linked_entry_id: Optional[UUID] created_at: datetime updated_at: datetime messages: List[MessageOut] = [] model_config = {"from_attributes": True} class TicketListResponse(BaseModel): data: List[TicketOut] pagination: dict