monitoring-api/packages/v1/administrativo/schemas/client_schema.py

116 lines
No EOL
4.5 KiB
Python

from pydantic import BaseModel, constr, field_validator, model_validator
from fastapi import HTTPException, status
from typing import Optional
from datetime import datetime
# Funções utilitárias para sanitização de entradas (evitar XSS, SQLi etc.)
# É necessário importar a função de sanitização se for utilizada nos validadores
from actions.validations.text import Text
# ----------------------------------------------------
# Schema base - Representa a estrutura completa do Cliente (usado em Show e Index)
# ----------------------------------------------------
class ClientSchema(BaseModel):
# Campos da DDL, todos opcionais para o Schema base (principalmente para leitura)
client_id: Optional[int] = None
cns: Optional[str] = None
name: Optional[str] = None
date_register: Optional[datetime] = None
state: Optional[str] = None
city: Optional[str] = None
responsible: Optional[str] = None
consultant: Optional[str] = None
type_contract: Optional[str] = None
status: Optional[str] = None
class Config:
# Permite que o Pydantic mapeie campos vindos do banco (ex: via ORM)
from_attributes = True
# ----------------------------------------------------
# Schema para operações que requerem apenas o ID
# ----------------------------------------------------
class ClientIdSchema(BaseModel):
client_id: Optional[int] = None
# Valida se o ID não está vazio
@model_validator(mode='after')
def validate_client_id(self):
if not self.client_id or self.client_id <= 0:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail='O ID do cliente é obrigatório para esta operação.'
)
return self
# ----------------------------------------------------
# Schema para localizar cliente pelo CNS
# ----------------------------------------------------
class ClientCNSSchema(BaseModel):
cns: Optional[str] = None
# Sanitiza o input
@field_validator('cns')
def sanitize_cns(cls, v):
if v:
return Text.sanitize_input(v) # Mantendo o padrão de sanitização
return v
# Valida se o campo não está vazio
@model_validator(mode='after')
def validate_cns(self):
if not self.cns or len(self.cns.strip()) == 0:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail='Informe um CNS para a busca.'
)
return self
# ----------------------------------------------------
# Schema para cadastrar (SAVE) um novo cliente (name é NOT NULL)
# ----------------------------------------------------
class ClientSaveSchema(BaseModel):
# Opcional, pois é AUTO_INCREMENT, mas pode ser usado para Upsert
client_id: Optional[int] = None
# name é NOT NULL na DDL, então é obrigatório no save
name: constr(min_length=1, max_length=550)
# Os demais são NULL DEFAULT ou com DEFAULT, então podem ser Optional na entrada
cns: Optional[str] = None
state: Optional[str] = None
city: Optional[str] = None
responsible: Optional[str] = None
consultant: Optional[str] = None
type_contract: Optional[str] = None
status: Optional[str] = None
# Sanitiza os inputs de string
@field_validator('cns', 'name', 'state', 'city', 'responsible', 'consultant', 'type_contract')
def validate_and_sanitize_fields(cls, v):
if v is not None:
# Assumindo que Text.sanitize_input existe e faz a sanitização
return Text.sanitize_input(v)
return v
# ----------------------------------------------------
# Schema para atualizar (UPDATE) um cliente (tudo opcional)
# ----------------------------------------------------
class ClientUpdateSchema(BaseModel):
# Todos os campos que podem ser atualizados são opcionais
cns: Optional[str] = None
name: Optional[constr(min_length=1, max_length=550)] = None
state: Optional[str] = None
city: Optional[str] = None
responsible: Optional[str] = None
consultant: Optional[str] = None
type_contract: Optional[str] = None
status: Optional[str] = None
# Sanitiza os inputs de string
@field_validator('cns', 'name', 'state', 'city', 'responsible', 'consultant', 'type_contract')
def validate_and_sanitize_fields(cls, v):
if v is not None:
# Assumindo que Text.sanitize_input existe e faz a sanitização
return Text.sanitize_input(v)
return v