2025-10-24 16:19:58 +03:00
|
|
|
|
"""
|
|
|
|
|
|
Pydantic модели для API
|
|
|
|
|
|
"""
|
|
|
|
|
|
from pydantic import BaseModel, Field, field_validator
|
|
|
|
|
|
from typing import Optional, List
|
|
|
|
|
|
from datetime import date
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SMSSendRequest(BaseModel):
|
|
|
|
|
|
"""Запрос на отправку SMS кода"""
|
|
|
|
|
|
phone: str = Field(..., description="Номер телефона в формате +79001234567")
|
|
|
|
|
|
|
|
|
|
|
|
@field_validator('phone')
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
def validate_phone(cls, v: str) -> str:
|
|
|
|
|
|
# Убираем все кроме цифр и +
|
|
|
|
|
|
clean = ''.join(c for c in v if c.isdigit() or c == '+')
|
|
|
|
|
|
if not clean.startswith('+'):
|
|
|
|
|
|
clean = '+' + clean
|
|
|
|
|
|
if len(clean) != 12: # +7 + 10 цифр
|
|
|
|
|
|
raise ValueError('Неверный формат телефона')
|
|
|
|
|
|
return clean
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SMSVerifyRequest(BaseModel):
|
|
|
|
|
|
"""Запрос на проверку SMS кода"""
|
|
|
|
|
|
phone: str = Field(..., description="Номер телефона")
|
|
|
|
|
|
code: str = Field(..., min_length=6, max_length=6, description="6-значный код")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ClaimCreateRequest(BaseModel):
|
|
|
|
|
|
"""Запрос на создание заявки"""
|
|
|
|
|
|
# Шаг 1: Основная информация
|
|
|
|
|
|
phone: str
|
|
|
|
|
|
email: Optional[str] = None
|
|
|
|
|
|
inn: Optional[str] = None
|
|
|
|
|
|
policy_number: str
|
|
|
|
|
|
policy_series: Optional[str] = None
|
|
|
|
|
|
|
|
|
|
|
|
# Шаг 2: Данные о происшествии
|
|
|
|
|
|
incident_date: Optional[str] = None
|
|
|
|
|
|
incident_description: Optional[str] = None
|
|
|
|
|
|
transport_type: Optional[str] = None # "air", "train", "bus", etc.
|
|
|
|
|
|
|
|
|
|
|
|
# Шаг 3: Данные для выплаты
|
|
|
|
|
|
payment_method: str = "sbp" # "sbp", "card", "bank_transfer"
|
|
|
|
|
|
bank_name: Optional[str] = None
|
|
|
|
|
|
card_number: Optional[str] = None
|
|
|
|
|
|
account_number: Optional[str] = None
|
|
|
|
|
|
|
|
|
|
|
|
# Файлы (UUID после загрузки)
|
|
|
|
|
|
uploaded_files: Optional[List[str]] = []
|
|
|
|
|
|
|
|
|
|
|
|
# Метаданные
|
|
|
|
|
|
source: str = "web_form"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ClaimResponse(BaseModel):
|
|
|
|
|
|
"""Ответ после создания заявки"""
|
|
|
|
|
|
success: bool
|
|
|
|
|
|
claim_id: Optional[str] = None
|
|
|
|
|
|
claim_number: Optional[str] = None
|
|
|
|
|
|
message: str
|
|
|
|
|
|
|
2025-11-14 19:06:36 +03:00
|
|
|
|
|
|
|
|
|
|
class TicketFormDescriptionRequest(BaseModel):
|
|
|
|
|
|
"""Отправка свободного описания проблемы (Ticket Form)"""
|
|
|
|
|
|
session_id: str = Field(..., description="ID клиентской сессии")
|
|
|
|
|
|
claim_id: Optional[str] = Field(None, description="ID заявки (если уже создана)")
|
|
|
|
|
|
phone: Optional[str] = Field(None, description="Номер телефона заявителя")
|
|
|
|
|
|
email: Optional[str] = Field(None, description="Email заявителя")
|
2025-11-26 19:54:51 +03:00
|
|
|
|
unified_id: Optional[str] = Field(None, description="Unified ID пользователя из PostgreSQL")
|
|
|
|
|
|
contact_id: Optional[str] = Field(None, description="Contact ID пользователя в CRM")
|
2025-11-14 19:06:36 +03:00
|
|
|
|
problem_description: str = Field(..., min_length=10, description="Свободное описание ситуации")
|
|
|
|
|
|
source: str = Field("ticket_form", description="Источник события")
|
|
|
|
|
|
channel: Optional[str] = Field(None, description="Переопределение Redis канала (опционально)")
|
|
|
|
|
|
|