from pydantic import BaseModel, constr, field_validator, validator from fastapi import HTTPException, status from typing import Optional from datetime import datetime # Funções para sanitização de entradas (evitar XSS, SQLi etc.) from actions.validations.text import Text # Funções para sanitização de entradas (evitar XSS, SQLi etc.) # É importante que esta função seja mantida/implementada no seu ambiente # from actions.validations.text import Text # Descomentar se for usar # ---------------------------------------------------- # Schema Base: Usado para leitura (GET, SHOW, INDEX) # Inclui todos os campos, incluindo os gerados pelo banco # ---------------------------------------------------- class AtoDocumentoSchema(BaseModel): ato_documento_id: Optional[int] = None ato_principal_id: Optional[int] = None # bigint NOT NULL arquivo: Optional[str] = None nome_documento: Optional[str] = None # varchar(255) NOT NULL tipo_documento: Optional[str] = None # varchar(50) NOT NULL created_at: Optional[datetime] = None updated_at: Optional[datetime] = None class Config: from_attributes = True # ---------------------------------------------------- # Schema para Requisição de ID: Usado em SHOW e DELETE # ---------------------------------------------------- class AtoDocumentoIdSchema(BaseModel): ato_documento_id: int @field_validator("ato_documento_id") def validate_ato_documento_id(cls, v: int): if v <= 0: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=[ { "input": "ato_documento_id", "message": "ID do documento deve ser um valor positivo.", } ], ) return v # ---------------------------------------------------- # Schema para Criação (SAVE): Campos obrigatórios e sem ID # ---------------------------------------------------- class AtoDocumentoSaveSchema(BaseModel): # Campo obrigatório ato_principal_id: int # Campos opcionais arquivo: Optional[str] = None nome_documento: Optional[str] = None tipo_documento: Optional[str] = None # Validação obrigatória para ato_principal_id @field_validator("ato_principal_id") def validate_ato_principal_id(cls, v): if v is None: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=[ { "input": "ato_principal_id", "message": "O campo 'ato_principal_id' deve ser informado.", } ], ) return v # Sanitização dos campos opcionais @field_validator("arquivo", "nome_documento", "tipo_documento", mode="before") def sanitize_optional_fields(cls, v: Optional[str]): if v is None: return None return Text.sanitize_input(v) # ---------------------------------------------------- # Schema para Atualização (UPDATE): Todos opcionais (parciais) # ---------------------------------------------------- class AtoDocumentoUpdateSchema(BaseModel): # Todos os campos são opcionais no UPDATE ato_principal_id: Optional[int] = None arquivo: Optional[str] = None nome_documento: Optional[constr(max_length=255)] = None tipo_documento: Optional[constr(max_length=50)] = None # Validação de Tipo Documento @field_validator("tipo_documento") def validate_tipo_documento(cls, v: Optional[str]): if v is None: return v v = v.strip() if not v: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=[ { "input": "tipo_documento", "message": "O tipo de documento não pode ser vazio.", } ], ) # Sanitiza o campo return Text.sanitize_input(v)