import logging from app.config import settings from app.schemas import Envelope, PayloadCompras from app.seguranca import autorizar from app.services import cripto from fastapi import APIRouter, Depends, HTTPException, status from pydantic import ValidationError router = APIRouter(prefix="/compras", tags=["compras"]) # Carregada uma vez no import: parsear PEM a cada request e desperdicio. _CHAVE = cripto.carregar_chave_privada(settings.vps.chave_privada) @router.post("/dados", dependencies=[Depends(autorizar)]) async def receber_compras(envelope: Envelope) -> dict: """ Recebe o envelope cifrado da API da VPS, abre e valida. Fase atual: so registra o que chegou. O INSERT no Oracle entra depois — quando entrar, tem que ser MERGE por id_processo, senao reentrega de webhook duplica linha. """ try: bruto = cripto.descriptografar(envelope.model_dump(), _CHAVE) except Exception as e: # Chave errada, envelope adulterado ou algoritmo diferente. logging.error(f"Falha ao abrir envelope: {type(e).__name__}: {e}") raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="envelope invalido" ) try: dados = PayloadCompras.model_validate(bruto) except ValidationError as e: # Decifrou mas o formato mudou: os dois lados sairam de sincronia. logging.error(f"Payload fora do contrato: {e}") raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="payload nao bate com o contrato esperado", ) logging.info( f"Compra recebida | processo={dados.id_processo} " f"protocolo={dados.protocolo} cnpj={dados.cnpj} " f"pedido={dados.pedido_linx} total={dados.valor_total} " f"parcelas={len(dados.parcelas)}" ) return { "status": "recebido", "id_processo": dados.id_processo, "parcelas": len(dados.parcelas), "persistido": False, # vira True quando o Oracle entrar }