""" Pydantic Schemas for Request/Response Models """ from pydantic import BaseModel, Field, validator from typing import Optional, List, Dict, Any from datetime import datetime from enum import Enum class ResultadoEnum(str, Enum): PROVIDO = "PROVIDO" PARCIALMENTE_PROVIDO = "PARCIALMENTE_PROVIDO" INDEFERIDO = "INDEFERIDO" JULGAR_EXTINTO = "JULGAR_EXTINTO" CONHECIDO_E_PROVIDO = "CONHECIDO_E_PROVIDO" CONHECIDO_E_PARCIALMENTE_PROVIDO = "CONHECIDO_E_PARCIALMENTE_PROVIDO" CONHECIDO_E_INDEFERIDO = "CONHECIDO_E_INDEFERIDO" class ProcessRequest(BaseModel): """Request para processar acórdão""" acordao_id: Optional[str] = None ementa: str = Field(..., min_length=10) integra: str = Field(..., min_length=50) tribunal: Optional[str] = None numero_processo: Optional[str] = None class Config: json_schema_extra = { "example": { "acordao_id": "ac_12345", "ementa": "APELAÇÃO CÍVEL. DIREITO DO CONSUMIDOR...", "integra": "Trata-se de apelação interposta...", "tribunal": "TJPR", "numero_processo": "0095039-32.2025.8.16.0000" } } class MetadadosResponse(BaseModel): """Metadados extraídos (Especialista 1)""" tribunal: str orgao_julgador: Optional[str] = None classe_processual: Optional[str] = None numero_processo: str relator: str data_julgamento: str ramo_especializado: str ramos_secundarios: List[Dict[str, str]] = [] contato_tribunal: Optional[Dict[str, str]] = None class TeseFragmentada(BaseModel): """Tese fragmentada do relatório""" parte: str nucleo_logico_argumentativo: str peso_merito: int = Field(ge=0, le=100) confianca_llm: int = Field(ge=0, le=100) etiquetas_semanticas: List[str] = [] elementos_factuais: List[Dict[str, Any]] = [] class RelatorioResponse(BaseModel): """Análise do relatório (Especialista 2)""" sintaxe_logica_argumentativa: str etiquetas_relatorio: List[str] teses_fragmentadas: List[TeseFragmentada] class FundamentoLegal(BaseModel): """Fundamento legal citado""" tipo: str citacao_fonte: str resumo_transcricao: Optional[str] = None class TeseRelator(BaseModel): """Tese do relator""" nucleo_logico_argumentativo: str fundamentos_legal: List[FundamentoLegal] confianca_llm: int = Field(ge=0, le=100) causalidade_merito: List[Dict[str, str]] = [] class FundamentacaoResponse(BaseModel): """Análise da fundamentação (Especialista 3)""" teses_relator: List[TeseRelator] temas_nao_conhecidos_omitidos: List[str] = [] class PedidoResultado(BaseModel): """Mapa de pedido e resultado""" pedido: str parte: str resultado_pedido: str valor_pedido: Optional[str] = None valor_concedido: Optional[str] = None fundamento_decisivo: str class DecisaoResponse(BaseModel): """Análise da decisão (Especialista 4)""" resultado: ResultadoEnum mapa_pedidos_resultado: List[PedidoResultado] fundamentos_decisivos: List[str] teses_geradas_decisao: List[Dict[str, Any]] = [] class ProcessResponse(BaseModel): """Response completo do processamento""" acordao_id: str status: str timestamp: datetime metadados: MetadadosResponse relatorio: Optional[RelatorioResponse] = None fundamentacao: Optional[FundamentacaoResponse] = None decisao: Optional[DecisaoResponse] = None processing_time_seconds: float especialistas_executados: List[str] class BatchProcessRequest(BaseModel): """Request para processamento em batch""" acordaos: List[ProcessRequest] especialistas: List[int] = Field(default=[1, 2, 3, 4], description="IDs dos especialistas (1-9)") async_mode: bool = False class BatchProcessResponse(BaseModel): """Response de batch""" batch_id: str total: int processed: int failed: int status: str results: List[ProcessResponse] = [] class StatusResponse(BaseModel): """Status de processamento""" batch_id: str status: str total: int processed: int failed: int progress_percent: float created_at: datetime updated_at: datetime class HealthResponse(BaseModel): """Health check response""" status: str timestamp: datetime version: str database: str redis: str llm_available: bool class ErrorResponse(BaseModel): """Error response""" error: str detail: Optional[str] = None timestamp: datetime path: Optional[str] = None