from __future__ import annotations from typing import Literal, Optional from pydantic import BaseModel, EmailStr, Field, ConfigDict, field_validator class NovoInquilinoRequest(BaseModel): model_config = ConfigDict(extra="forbid") # rejeita campos desconhecidos nome: str = Field(..., min_length=1, description="Nome do cliente/inquilino") email: EmailStr password: str = Field(..., min_length=6) cpf_cnpj: str = Field(..., min_length=11, max_length=18, description="CPF/CNPJ com ou sem máscara") # @field_validator("nome") # @classmethod # def _strip_nome(cls, v: str) -> str: # v = v.strip() # if not v: # raise ValueError("Nome não pode ser vazio") # return " ".join(v.split()) # colapsa espaços internos # # @field_validator("cpf_cnpj", mode="before") # @classmethod # def _sanitize_cpf_cnpj(cls, v: str) -> str: # # remove tudo que não for dígito # if isinstance(v, str): # digits = "".join(ch for ch in v if ch.isdigit()) # return digits # return v # # @field_validator("cpf_cnpj") # @classmethod # def _validate_cpf_cnpj_len(cls, v: str) -> str: # # valida tamanho (11 = CPF, 14 = CNPJ). Validação algorítmica pode ficar na classe de validações especiais depois # if len(v) not in (11, 14): # raise ValueError("CPF/CNPJ deve ter 11 (CPF) ou 14 (CNPJ) dígitos após sanitização") # return v # # @field_validator("subdominio") # @classmethod # def _normalize_subdominio(cls, v: Optional[str]) -> Optional[str]: # if v is None: # return v # v = v.strip().lower() # if not v: # return None # return v class NovoInquilinoResponse(BaseModel): model_config = ConfigDict(extra="ignore") tenant: str status: Literal["active", "failed", "provisioning"] schema_name: Optional[str] = None subdominio: Optional[str] = None alembic_stdout: Optional[str] = None