import re from enum import Enum from pydantic import BaseModel, Field, validator from typing import Optional, Dict, Any class CallSide(str, Enum): DRIVER = "driver" BOT = "bot" class CallStatus(str, Enum): PENDING = "PENDING" RUNNING = "RUNNING" COMPLETED = "COMPLETED" ALL_MISSED = "ALL_MISSED" FAILED = "FAILED" class CheckType(str, Enum): period = "period" specifically = "specifically" class Operations(Enum): eq = "==", gt = ">", gte = ">=", lt = "<", lte = "<=" class AccessResponse(BaseModel): success: bool token: str class Registration(BaseModel): auth_key: str class User(BaseModel): id: Optional[int] = Field(description="Идентификатор (автоматический)", default=None) username: str = Field(max_length=150, description="Пользовательское имя", example="john_doe") #password: str = Field(max_length=255, description="Пароль", example="secret123") email: Optional[str] = Field(max_length=254, default="", description="Электронная почта", example="john@example.com") first_name: Optional[str] = Field(max_length=150, default="", description="Имя", example="John") last_name: Optional[str] = Field(max_length=150, default="", description="Фамилия", example="Doe") #is_staff: bool = Field(default=False, description="Статус администратора") #is_active: bool = Field(default=False, description="Активен") #is_superuser: bool = Field(default=False, description="Суперпользователь") #date_joined: str = Field(description="Дата создания", example="2024-01-01T12:00:00") #last_login: Optional[str] = Field(null=True, default=None, description="Последний вход") class Config: extra = "ignore" from_attributes = True class BasicModel(BaseModel): id: Optional[int] = Field(description="Идентификатор (автоматический)", default=None) created_at: Optional[str] = Field(description="Дата создания", example="2024-01-01T12:00:00") updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00") class Config: extra = "ignore" from_attributes = True class UUIDModel(BaseModel): unique_id: str = Field(description="Уникальный идентификатор", example="00000000-0000-0000-0000-000000000000") class CallPrompt(BasicModel): owner: Optional[User] = Field(description="Владелец") name: str = Field(max_length=255, description="Название промпта", example="Приветствие клиенту") content: str = Field(description="Содержание промпта", example="Добро пожаловать в службу поддержки") speak_first: bool = Field(default=True, description="Говорить первым") can_interrupt_greeting: bool = Field(default=False, description="Может прерывать приветствие") class Config: extra = "ignore" from_attributes = True class YandexFleet(BasicModel): owner: Optional[User] = Field(description="Владелец") name: str = Field(max_length=255, description="Название флота", example="Флот такси") park_id: str = Field(max_length=255, description="ID флота в Yandex", example="park-12345") timezone: str = Field( max_length=255, default="Europe/Moscow", description="Часовой пояс", example="Europe/Moscow" ) class Config: extra = "ignore" from_attributes = True class YandexFleetApiKey(UUIDModel, BasicModel): yandex_fleet: YandexFleet api_key: str class Driver(BasicModel): yandex_fleet: Optional[YandexFleet] = Field(description="ID или название флота Yandex", example="fleet-123") driver_id: str = Field(max_length=64, description="ID драйвера в Yandex", example="drv-abc123") created_at: Optional[str] = Field(description="Дата создания", example="2024-01-01T12:00:00") updated_at: Optional[str] = Field(description="Дата обновления", example="2024-01-01T12:00:00") class Config: extra = "ignore" from_attributes = True class DriversGroup(BasicModel, UUIDModel): owner: User = Field(description="Владелец группы") drivers: Optional[List[Driver]] = Field(description="Список водителей в группе", default=[]) name: str = Field( ..., max_length=255, description="Название группы" ) class Call(UUIDModel, BasicModel): owner: Optional[User] = Field(description="Владелец", default=None) call_datetime: Optional[str] = Field(description="Время последнего звонка (по МСК)", example="2024-01-01T12:00:00", default=None) prompt: Optional[CallPrompt] = Field(description="Промпт", default=None) driver: Optional[Driver] = Field(description="Водитель") status: Optional[CallStatus] = Field(default=CallStatus.PENDING, description="Статус звонка") data: Optional[Dict[str, Any]] = Field(description="Дополнительные данные", nullable=True, default=None) channel_id: Optional[str] = Field(description="ID канала", example=" tweak-456", default=None) audio_file: Optional[str] = Field(description="Путь к аудио", example="/audio/call-123.mp3", default=None) class Config: extra = "ignore" from_attributes = True class CallIn(BaseModel): owner_id: int = Field(description="Владелец") call_datetime: Optional[str] = Field(description="Время последнего звонка (по МСК)", example="2024-01-01T12:00:00", default=None) prompt_id: int = Field(description="Промпт",) driver_id: int = Field(description="Водитель") status: CallStatus = Field(default=CallStatus.PENDING, description="Статус звонка") data: Optional[Dict[str, Any]] = Field(description="Дополнительные данные", nullable=True, default=None) channel_id: Optional[str] = Field(description="ID канала", example=" tweak-456", null=True, default=None) audio_file: Optional[str] = Field(description="Путь к аудио", example="/audio/call-123.mp3", null=True, default=None) class Config: extra = "ignore" from_attributes = True class InspectionWorkTime(BasicModel, UUIDModel): owner: User = Field(description="Владелец", example={"id": 1, "username": "admin"}) is_public: Optional[bool] = Field(default=False, description="Открыт для всех") check_from: Optional[str] = Field( default="08:00:00", description="Время начала проверки", pattern=r"^(2[0-3]|[01]\d):([0-5]\d):([0-5]\d)$" ) check_to: Optional[str] = Field( default="22:00:00", description="Время окончания проверки", pattern=r"^(2[0-3]|[01]\d):([0-5]\d):([0-5]\d)$" ) monday: Optional[bool] = Field(default=False, description="Понедельник") tuesday: Optional[bool] = Field(default=False, description="Вторник") wednesday: Optional[bool] = Field(default=False, description="Среда") thursday: Optional[bool] = Field(default=False, description="Четверг") friday: Optional[bool] = Field(default=False, description="Пятница") saturday: Optional[bool] = Field(default=False, description="Суббота") sunday: Optional[bool] = Field(default=False, description="Воскресенье") class Config: extra = "ignore" from_attributes = True class CallDriver(BasicModel, UUIDModel): owner: Optional[User] = Field(default=None, description="Владелец (пользователь)") prompt: Optional[CallPrompt] = Field(default=None, description="Промпт для звонка") class Config: extra = "ignore" from_attributes = True class SupplyHoursCondition(BasicModel, UUIDModel): for_days: Optional[int] = Field(default=0, description="Дни", ge=-2147483648, le=2147483647) for_hours: Optional[int] = Field(default=0, description="Часы", ge=-2147483648, le=2147483647) for_minutes: Optional[int] = Field(default=0, description="Минуты", ge=-2147483648, le=2147483647) target_time: int = Field(description="Целевой временной интервал", ge=-2147483648, le=2147483647) operator: Operations = Field(description="Оператор", default=Operations.gte) class Config: extra = "ignore" from_attributes = True class Action(BasicModel, UUIDModel): owner: Optional[User] = Field(..., description="Владелец объекта", default=None) call_driver_action: Optional[CallDriver] = Field( default=None, description="Действие по вызову водителя", ) class Condition(BasicModel, UUIDModel): owner: Optional[User] = Field(..., description="Владелец условия", default=None) supply_hours_condition: Optional[SupplyHoursCondition] = Field(..., description="Условие по часам поставки") class ConditionalExpression(BasicModel, UUIDModel): owner: Optional[User] = Field(..., description="Владелец условия", default=None) condition: Optional[Condition] = Field( default=None, description="Условие (например, `SupplyHoursCondition`)", ) true_action: Optional[Action] = Field( default=None, description="Действие, если условие истинно", ) false_action: Optional[Action] = Field( default=None, description="Действие, если условие ложно", ) class Check(BasicModel, UUIDModel): owner: Optional[User] = Field( ..., description="Владелец проверки", default=None ) check_type: CheckType = Field( ..., description="Тип проверки", default=CheckType.period ) time: Optional[str] = Field( default="12:00:00", description="Время проверки (в формате hh:mm:ss)", format="time" ) class BaseInspectionModel(UUIDModel): owner: Optional[User] = Field(..., description="Владелец проверки", default=None) name : str = Field(..., description="Название проверки") work_time: Optional[InspectionWorkTime] = Field(None, description="Рабочее время") class BaseInspectionsCheckModel(UUIDModel): owner: Optional[User] = Field(..., description="Владелец проверки", default=None) check_obj: Optional[Check] = Field(..., description="Проверка", default=None) conditional_expression: Optional[ConditionalExpression] = Field(..., description="Условное выражение", default=None) last_check: Optional[str] = Field(default=None, description="Последняя проверка", format="date-time") class YandexFleetInspection(BaseInspectionModel, BasicModel): yandex_fleet: YandexFleet = Field(..., description="Флот") class GroupInspection(BaseInspectionModel, BasicModel): group: DriversGroup = Field(..., description="Группа") class DriverInspection(BaseInspectionModel, BasicModel): driver: Driver = Field(..., description="Водитель") class YandexFleetInspectionCheeks(BaseInspectionsCheckModel, BasicModel): yandex_fleet_inspection: YandexFleetInspection = Field(..., description="Инспекция флота") class GroupInspectionCheek(BaseInspectionsCheckModel, BasicModel): group_inspection: GroupInspection = Field(..., description="Инспекция группы") class DriverInspectionCheek(BaseInspectionsCheckModel, BasicModel): driver_inspection: DriverInspection = Field(..., description="Инспекция водителя")