FlotillasGPS - Sistema completo de monitoreo de flotillas GPS
Sistema completo para monitoreo y gestion de flotas de vehiculos con: - Backend FastAPI con PostgreSQL/TimescaleDB - Frontend React con TypeScript y TailwindCSS - App movil React Native con Expo - Soporte para dispositivos GPS, Meshtastic y celulares - Video streaming en vivo con MediaMTX - Geocercas, alertas, viajes y reportes - Autenticacion JWT y WebSockets en tiempo real Documentacion completa y guias de usuario incluidas.
This commit is contained in:
116
backend/app/schemas/usuario.py
Normal file
116
backend/app/schemas/usuario.py
Normal file
@@ -0,0 +1,116 @@
|
||||
"""
|
||||
Schemas Pydantic para Usuario.
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, EmailStr, Field, field_validator
|
||||
|
||||
from app.schemas.base import BaseSchema, TimestampSchema
|
||||
|
||||
|
||||
class UsuarioBase(BaseSchema):
|
||||
"""Schema base de usuario."""
|
||||
|
||||
email: EmailStr
|
||||
nombre: str = Field(..., min_length=2, max_length=100)
|
||||
apellido: Optional[str] = Field(None, max_length=100)
|
||||
telefono: Optional[str] = Field(None, max_length=20)
|
||||
|
||||
|
||||
class UsuarioCreate(UsuarioBase):
|
||||
"""Schema para crear usuario."""
|
||||
|
||||
password: str = Field(..., min_length=8, max_length=100)
|
||||
es_admin: bool = False
|
||||
|
||||
@field_validator("password")
|
||||
@classmethod
|
||||
def validate_password(cls, v: str) -> str:
|
||||
if len(v) < 8:
|
||||
raise ValueError("La contraseña debe tener al menos 8 caracteres")
|
||||
if not any(c.isupper() for c in v):
|
||||
raise ValueError("La contraseña debe tener al menos una mayúscula")
|
||||
if not any(c.islower() for c in v):
|
||||
raise ValueError("La contraseña debe tener al menos una minúscula")
|
||||
if not any(c.isdigit() for c in v):
|
||||
raise ValueError("La contraseña debe tener al menos un número")
|
||||
return v
|
||||
|
||||
|
||||
class UsuarioUpdate(BaseSchema):
|
||||
"""Schema para actualizar usuario."""
|
||||
|
||||
nombre: Optional[str] = Field(None, min_length=2, max_length=100)
|
||||
apellido: Optional[str] = Field(None, max_length=100)
|
||||
telefono: Optional[str] = Field(None, max_length=20)
|
||||
avatar_url: Optional[str] = None
|
||||
preferencias: Optional[str] = None
|
||||
|
||||
|
||||
class UsuarioUpdatePassword(BaseModel):
|
||||
"""Schema para cambiar contraseña."""
|
||||
|
||||
password_actual: str
|
||||
password_nuevo: str = Field(..., min_length=8, max_length=100)
|
||||
|
||||
@field_validator("password_nuevo")
|
||||
@classmethod
|
||||
def validate_password(cls, v: str) -> str:
|
||||
if len(v) < 8:
|
||||
raise ValueError("La contraseña debe tener al menos 8 caracteres")
|
||||
return v
|
||||
|
||||
|
||||
class UsuarioResponse(UsuarioBase, TimestampSchema):
|
||||
"""Schema de respuesta de usuario."""
|
||||
|
||||
id: int
|
||||
es_admin: bool
|
||||
activo: bool
|
||||
ultimo_acceso: Optional[datetime] = None
|
||||
avatar_url: Optional[str] = None
|
||||
|
||||
|
||||
class UsuarioInDB(UsuarioResponse):
|
||||
"""Schema interno con hash de password."""
|
||||
|
||||
password_hash: str
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Schemas de Autenticación
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class LoginRequest(BaseModel):
|
||||
"""Schema para solicitud de login."""
|
||||
|
||||
email: EmailStr
|
||||
password: str
|
||||
|
||||
|
||||
class LoginResponse(BaseModel):
|
||||
"""Schema de respuesta de login."""
|
||||
|
||||
access_token: str
|
||||
refresh_token: str
|
||||
token_type: str = "bearer"
|
||||
expires_in: int
|
||||
user: UsuarioResponse
|
||||
|
||||
|
||||
class RefreshTokenRequest(BaseModel):
|
||||
"""Schema para refresh token."""
|
||||
|
||||
refresh_token: str
|
||||
|
||||
|
||||
class TokenResponse(BaseModel):
|
||||
"""Schema de respuesta de tokens."""
|
||||
|
||||
access_token: str
|
||||
refresh_token: str
|
||||
token_type: str = "bearer"
|
||||
expires_in: int
|
||||
Reference in New Issue
Block a user