"""Modelos Pydantic para validación de datos""" from pydantic import BaseModel, EmailStr, Field from typing import Optional from datetime import datetime class RegistroRequest(BaseModel): """Modelo para crear un nuevo registro""" uid: str = Field(..., max_length=255, description="UID de Firestore") display_name: str = Field(..., min_length=1, max_length=255, description="Nombre a mostrar") pais: str = Field(..., min_length=1, max_length=255, description="País del usuario") correo: EmailStr = Field(..., description="Email del usuario") fecha_registro: Optional[datetime] = Field(None, description="Fecha de registro") usos: Optional[int] = Field(0, ge=0, description="Cantidad de usos") prompt: Optional[str] = Field(None, max_length=255, description="Prompt utilizado") prompt_type: Optional[str] = Field(None, max_length=255, description="Tipo de prompt") prompt_eval: Optional[str] = Field(None, max_length=255, description="Evaluación del prompt") estilo: Optional[str] = Field(None, max_length=255, description="Estilo para la generación") estilo_agregado: Optional[str] = Field(None, max_length=255, description="Estilo adicional") calificacion: Optional[int] = Field(None, ge=0, description="Calificación numérica") proveedor: Optional[str] = Field(None, max_length=255, description="Proveedor del servicio") seed: Optional[int] = Field(None, description="Seed para generación") class Config: example = { "uid": "usuario123", "display_name": "Juan Pérez", "pais": "España", "correo": "juan@example.com", "prompt": "crear imagen de perro", "prompt_type": "imagen", "prompt_eval": "muy buena calidad", "estilo": "realista", "estilo_agregado": "alto detalle", "calificacion": 9, "proveedor": "openai", "seed": 12345 } class RegistroResponse(BaseModel): """Modelo para respuesta de registro""" id: int = Field(..., description="ID único del registro (auto-incremental)") uid: str = Field(..., description="UID de Firestore") display_name: str pais: str correo: str fecha_registro: Optional[datetime] usos: int prompt: Optional[str] prompt_type: Optional[str] prompt_eval: Optional[str] estilo: Optional[str] estilo_agregado: Optional[str] calificacion: Optional[int] proveedor: Optional[str] seed: Optional[int] created_at: datetime class Config: example = { "id": "550e8400-e29b-41d4-a716-446655440000", "display_name": "Juan Pérez", "pais": "España", "correo": "juan@example.com", "fecha_registro": "2025-01-13T10:30:00", "usos": 0, "prompt": "crear imagen de perro", "proveedor": "openai", "seed": 12345, "created_at": "2025-01-13T10:30:00" } class CalificacionRequest(BaseModel): """Modelo para actualizar calificación de un registro""" id: int = Field(..., gt=0, description="ID del registro a calificar") calificacion: int = Field(..., ge=0, description="Calificación numérica") class Config: example = { "id": 1, "calificacion": 8 } class ActionRequest(BaseModel): """Modelo para crear/actualizar un registro en la tabla action_call""" usuario: str = Field(..., max_length=255, description="Nombre de usuario único") uid: Optional[str] = Field(None, max_length=255, description="UID de Firestore") displayName: Optional[str] = Field(None, max_length=255, description="Nombre a mostrar") email: Optional[str] = Field(None, description="Email del usuario") action_call: Optional[bool] = Field(None, description="Llamada a acción") trigger_action: Optional[str] = Field(None, max_length=255, description="Trigger de acción") country_header: Optional[str] = Field(None, max_length=10, description="País del header") country_ip: Optional[str] = Field(None, max_length=10, description="País de la IP") creditos: Optional[int] = Field(None, description="Créditos disponibles") esta_hora: Optional[int] = Field(None, ge=0, description="Usos esta hora") explicit_counter: Optional[int] = Field(None, ge=0, description="Contador explícito") fecha_registro: Optional[datetime] = Field(None, description="Fecha de registro") gaClient: Optional[str] = Field(None, max_length=255, description="Cliente de Google Analytics") open_use: Optional[bool] = Field(None, description="Uso abierto") ritmo: Optional[float] = Field(None, description="Ritmo de uso") streak: Optional[int] = Field(None, ge=0, description="Racha de usos") ultima_generacion_hora: Optional[datetime] = Field(None, description="Última generación esta hora") ultimo_uso: Optional[datetime] = Field(None, description="Último uso") usos: Optional[int] = Field(None, ge=0, description="Total de usos") class Config: example = { "usuario": "moibe", "uid": "uTHjWOudaUYXDgTDE3zlvlr5QU63", "displayName": "Moisés Briseño Estrello", "email": "moi.estrello@gmail.com", "action_call": True, "trigger_action": "generacion_imagen", "country_header": "BR", "country_ip": "BR", "creditos": 0, "esta_hora": 2, "explicit_counter": 14, "usos": 201 } class ActionResponse(BaseModel): """Modelo para respuesta de acciones""" id: int usuario: str uid: Optional[str] displayName: Optional[str] email: Optional[str] action_call: Optional[bool] trigger_action: Optional[str] country_header: Optional[str] country_ip: Optional[str] creditos: Optional[int] esta_hora: Optional[int] explicit_counter: Optional[int] fecha_registro: Optional[datetime] gaClient: Optional[str] open_use: Optional[bool] ritmo: Optional[float] streak: Optional[int] ultima_generacion_hora: Optional[datetime] ultimo_uso: Optional[datetime] usos: Optional[int] created_at: datetime updated_at: datetime class Config: example = { "id": 1, "usuario": "moibe", "uid": "uTHjWOudaUYXDgTDE3zlvlr5QU63", "displayName": "Moisés Briseño Estrello", "email": "moi.estrello@gmail.com", "usos": 201, "created_at": "2025-01-13T10:30:00", "updated_at": "2025-02-06T15:45:00" } class FunelCompraRequest(BaseModel): """Modelo para crear/registrar un evento en el funel de compra""" usuario: str = Field(..., max_length=255, description="Nombre de usuario") mail: str = Field(..., description="Email del usuario") accion: str = Field(..., max_length=255, description="Acción realizada en el funel (ej: inicio, visualizacion, intento_compra, compra_exitosa)") class Config: example = { "usuario": "moibe", "mail": "moi.estrello@gmail.com", "accion": "compra_exitosa" } class FunelCompraResponse(BaseModel): """Modelo para respuesta de registros del funel de compra""" id: int = Field(..., description="ID único del registro") usuario: str mail: str accion: str created_at: datetime class Config: example = { "id": 1, "usuario": "moibe", "mail": "moi.estrello@gmail.com", "accion": "compra_exitosa", "created_at": "2026-02-11T10:30:00" }