diff --git a/.env.example b/.env.example index 07152bf..3b78997 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,14 @@ GOOGLE_PROJECT_ID=seu-projeto-id GOOGLE_LOCATION=us-central1 + + +# Database +DB_HOST=Seu_host +DB_PORT=3306 +DB_USER=Seu_usuario +DB_PASSWORD=Sua_senha +DB_NAME=Seu_banco_de_dados + +# Mockaroo +MOCKAROO_API_KEY=coloque_sua_api_key_aqui +MOCKAROO_BASE_URL=https://my.api.mockaroo.com \ No newline at end of file diff --git a/app/api/schemas.py b/app/api/schemas.py index 6142e85..b518003 100644 --- a/app/api/schemas.py +++ b/app/api/schemas.py @@ -1,5 +1,5 @@ from pydantic import BaseModel -from typing import Dict, Any +from typing import Dict, Any, Optional class ChatRequest(BaseModel): message: str @@ -9,7 +9,6 @@ class ChatResponse(BaseModel): response: str - class ToolCreate(BaseModel): name: str description: str @@ -23,4 +22,30 @@ class ToolResponse(BaseModel): parameters: Dict[str, Any] class Config: - from_attributes = True \ No newline at end of file + from_attributes = True + + +class ConsultarEstoqueRequest(BaseModel): + preco_max: float + categoria: Optional[str] = None + + +class ValidarClienteVendaRequest(BaseModel): + cpf: str + valor_veiculo: float + + +class AvaliarVeiculoTrocaRequest(BaseModel): + modelo: str + ano: int + km: int + + +class AgendarRevisaoRequest(BaseModel): + placa: str + data_hora: str + + +class CancelarPedidoRequest(BaseModel): + numero_pedido: str + motivo: str diff --git a/app/core/settings.py b/app/core/settings.py index d3f35eb..33f9810 100644 --- a/app/core/settings.py +++ b/app/core/settings.py @@ -12,6 +12,10 @@ class Settings(BaseSettings): db_password: str db_name: str + mockaroo_api_key: str + mockaroo_base_url: str = "https://api.mockaroo.com/api" + use_mockaroo_writes: bool = False + class Config: env_file = ".env" diff --git a/app/services/handlers.py b/app/services/handlers.py new file mode 100644 index 0000000..bf8363f --- /dev/null +++ b/app/services/handlers.py @@ -0,0 +1,92 @@ +from typing import Optional, List, Dict, Any +import re +import uuid +from datetime import datetime + +from app.services.mockaroo_client import MockarooClient +from app.core.settings import settings + + +def normalize_cpf(value: str) -> str: + return re.sub(r"\D", "", value or "") + + +async def consultar_estoque(preco_max: float, categoria: Optional[str] = None) -> List[Dict[str, Any]]: + client = MockarooClient() + registros = await client.fetch_schema_data("consultar_estoque", count=200) + return [ + r for r in registros + if float(r.get("preco", 0)) <= preco_max and (categoria is None or r.get("categoria") == categoria) + ] + + +async def validar_cliente_venda(cpf: str, valor_veiculo: float) -> Dict[str, Any]: + client = MockarooClient() + registros = await client.fetch_schema_data("clientes_credito", count=500) + cpf_norm = normalize_cpf(cpf) + cliente = next((r for r in registros if normalize_cpf(r.get("cpf", "")) == cpf_norm), None) + if not cliente: + return { + "aprovado": False, + "motivo": "Cliente não encontrado", + "cpf": cpf_norm, + "valor_veiculo": valor_veiculo, + } + limite = float(cliente.get("limite_credito", 0)) + restricao = bool(cliente.get("possui_restricao", False)) + aprovado = (not restricao) and (valor_veiculo <= limite) + return { + "aprovado": aprovado, + "cpf": cpf_norm, + "nome": cliente.get("nome"), + "score": cliente.get("score"), + "limite_credito": limite, + "possui_restricao": restricao, + "valor_veiculo": valor_veiculo, + } + + +async def avaliar_veiculo_troca(modelo: str, ano: int, km: int) -> Dict[str, Any]: + ano_atual = datetime.now().year + idade = max(0, ano_atual - ano) + base = 80000.0 + valor = base * (0.85 ** idade) - (km * 0.03) + valor = max(5000.0, valor) + return { + "modelo": modelo, + "ano": ano, + "km": km, + "valor_estimado_troca": round(valor, 2), + } + + +async def agendar_revisao(placa: str, data_hora: str) -> Dict[str, Any]: + if settings.use_mockaroo_writes: + client = MockarooClient() + try: + return await client.post_json( + "agendamentos_revisao", + {"placa": placa, "data_hora": data_hora, "status": "Agendado"}, + ) + except Exception: + pass + agendamento_id = str(uuid.uuid4()) + return {"id": agendamento_id, "placa": placa, "data_hora": data_hora, "status": "Agendado"} + + +async def cancelar_pedido(numero_pedido: str, motivo: str) -> Dict[str, Any]: + client = MockarooClient() + registros = await client.fetch_schema_data("pedidos", count=500) + pedido = next((r for r in registros if str(r.get("numero_pedido")) == str(numero_pedido)), None) + if not pedido: + return { + "status": "NaoEncontrado", + "numero_pedido": numero_pedido, + "motivo": motivo, + } + if settings.use_mockaroo_writes: + try: + await client.delete_json("pedidos", {"numero_pedido": numero_pedido, "motivo": motivo}) + except Exception: + pass + return {"status": "Cancelado", "numero_pedido": numero_pedido, "motivo": motivo, "pedido": pedido} diff --git a/app/services/mockaroo_client.py b/app/services/mockaroo_client.py new file mode 100644 index 0000000..598d9ce --- /dev/null +++ b/app/services/mockaroo_client.py @@ -0,0 +1,60 @@ +from typing import Any, Dict, List, Optional + +import httpx + +from app.core.settings import settings + +class MockarooClient: + def __init__( + self, + api_key: Optional[str] = None, + base_url: Optional[str] = None, + ): + self.api_key = api_key or settings.mockaroo_api_key + self.base_url = (base_url or settings.mockaroo_base_url).rstrip("/") + + async def fetch_schema_data( + self, + schema_name: str, + count: int = 100, + extra_params: Optional[Dict[str, Any]] = None, + ) -> List[Dict[str, Any]]: + url = f"{self.base_url}/{schema_name}" + params: Dict[str, Any] = { + "key": self.api_key, + "count": count, + } + if extra_params: + params.update(extra_params) + + async with httpx.AsyncClient() as client: + response = await client.get(url, params=params) + response.raise_for_status() + data = response.json() + if isinstance(data, list): + return data + return [data] + + async def post_json(self, route: str, payload: Dict[str, Any]) -> Dict[str, Any]: + url = f"{self.base_url}/{route}" + params = {"key": self.api_key} + async with httpx.AsyncClient() as client: + response = await client.post(url, params=params, json=payload) + response.raise_for_status() + return response.json() + + async def put_json(self, route: str, payload: Dict[str, Any]) -> Dict[str, Any]: + url = f"{self.base_url}/{route}" + params = {"key": self.api_key} + async with httpx.AsyncClient() as client: + response = await client.put(url, params=params, json=payload) + response.raise_for_status() + return response.json() + + async def delete_json(self, route: str, payload: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: + url = f"{self.base_url}/{route}" + params = {"key": self.api_key} + async with httpx.AsyncClient() as client: + response = await client.delete(url, params=params, json=payload or {}) + response.raise_for_status() + return response.json()