Guia Uso Apis 4C Decision

Guia de Uso - APIs /4c/decision (4C Decision API)

Base URL: https://csuite.internut.com.br/4c/decision

Documentação Swagger: https://csuite.internut.com.br/4c/decision/docs

OpenAPI Spec: https://csuite.internut.com.br/4c/decision/openapi.json


📋 Índice

  1. Visão Geral
  2. Decisão Completa
  3. Decisão Automática
  4. Decisão em Lote
  5. Candidatos Automáticos
  6. Executar Ação
  7. Versionamento
  8. Health & Metrics
  9. Exemplos Práticos
  10. Troubleshooting

1. Visão Geral

O 4C Decision API é o orquestrador de decisões do sistema 4 Certos Dinâmico, responsável por:

Características:
- ✅ API REST assíncrona (FastAPI)
- ✅ Versionamento (/v1/...)
- ✅ Integração com Feature Service, Scoring Service, Executor
- ✅ Rate limiting configurável (120 req/min para /decide, 240 req/min para /send)
- ✅ Telemetria em ClickHouse
- ✅ Métricas Prometheus


2. Decisão Completa

Endpoint: POST /decide ou POST /v1/decide

Descrição: Solicita uma decisão completa para um cliente, incluindo oferta, canal e timing.

Request:

{
  "customer_id": 123,
  "org_id": 1,
  "candidates": [
    {
      "sku": "BK4-2516",
      "price": 1500.00
    },
    {
      "sku": "BK4-2517",
      "price": 2000.00
    }
  ],
  "constraints": {
    "min_intent": 0.45,
    "max_contacts_per_day": 2,
    "respect_opt_out": true
  },
  "include_explanations": true,
  "include_natural_justification": false
}

Parâmetros:
- customer_id (int, obrigatório) - ID do cliente
- org_id (int, opcional) - ID da organização (para carregar políticas do CSuite)
- candidates (array, opcional) - Lista de ofertas candidatas. Se vazio, usa decisão automática
- constraints (object, opcional) - Constraints manuais (sobrescrevem políticas do CSuite)
- min_intent (float) - Score mínimo de intenção (0.0-1.0)
- max_contacts_per_day (int) - Máximo de contatos por dia
- respect_opt_out (bool) - Respeitar opt-out do cliente
- include_explanations (bool, padrão: false) - Incluir explicações SHAP
- include_natural_justification (bool, padrão: false) - Gerar justificativa natural via LLM (requer include_explanations=true)

Response (Aprovada):

{
  "decision_id": "uuid-123",
  "approved": true,
  "customer_id": 123,
  "offer": {
    "sku": "BK4-2516",
    "price": 1500.00,
    "margin_pct": 25.5
  },
  "channel": "whatsapp",
  "timing": {
    "send_at": "2025-01-27T14:30:00Z",
    "score": 0.85
  },
  "scores": {
    "intent": 0.72,
    "offer": 0.88,
    "channel": 0.91,
    "timing": 0.85
  },
  "explanations": {
    "intent": {
      "factors": [
        {
          "feature": "recency_days",
          "value": 15,
          "shap": 0.12
        },
        {
          "feature": "freq_12m",
          "value": 5,
          "shap": 0.08
        }
      ]
    }
  },
  "natural_justification": "Recomendamos este produto porque o cliente tem histórico de compras recentes e demonstrou interesse em produtos similares."
}

Response (Pulada):

{
  "decision_id": "uuid-123",
  "approved": false,
  "skip_reason": "low_intent",
  "customer_id": 123,
  "scores": {
    "intent": 0.35
  }

Exemplo:

curl -X POST "https://csuite.internut.com.br/4c/decision/decide" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": 123,
    "org_id": 1,
    "candidates": [
      {"sku": "BK4-2516", "price": 1500.00}
    ],
    "include_explanations": true
  }'

Casos de uso:
- Decisão 1:1 com cliente específico
- Campanhas segmentadas
- Cross-sell e up-sell
- Recuperação de carrinho abandonado


3. Decisão Automática

Endpoint: POST /decide/auto ou POST /v1/decide/auto

Descrição: Decisão automática sem candidatos (sistema escolhe automaticamente a melhor oferta).

Request:

{
  "customer_id": 123,
  "org_id": 1,
  "include_explanations": true,
  "include_natural_justification": true
}

Parâmetros:
- customer_id (int, obrigatório) - ID do cliente
- org_id (int, opcional) - ID da organização
- include_explanations (bool, padrão: false) - Incluir explicações SHAP
- include_natural_justification (bool, padrão: false) - Gerar justificativa natural via LLM

Response:

{
  "decision_id": "uuid-123",
  "approved": true,
  "customer_id": 123,
  "offer": {
    "sku": "BK4-2516",
    "price": 1500.00
  },
  "channel": "whatsapp",
  "timing": {
    "send_at": "2025-01-27T14:30:00Z"
  },
  "scores": {
    "intent": 0.72,
    "offer": 0.88,
    "channel": 0.91,
    "timing": 0.85
  }
}

Exemplo:

curl -X POST "https://csuite.internut.com.br/4c/decision/decide/auto" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": 123,
    "org_id": 1
  }'

Casos de uso:
- Decisões em massa (batch)
- Automação completa
- Quando não há candidatos pré-definidos


4. Decisão em Lote

Endpoint: POST /decide/batch/auto ou POST /v1/decide/batch/auto

Descrição: Decisões automáticas para múltiplos clientes.

Request:

{
  "customer_ids": [123, 456, 789],
  "org_id": 1,
  "include_explanations": false
}

Parâmetros:
- customer_ids (array[int], obrigatório) - Lista de IDs de clientes
- org_id (int, opcional) - ID da organização
- include_explanations (bool, padrão: false) - Incluir explicações

Response:

{
  "decisions": [
    {
      "decision_id": "uuid-123",
      "customer_id": 123,
      "approved": true,
      "offer": {"sku": "BK4-2516", "price": 1500.00},
      "channel": "whatsapp"
    },
    {
      "decision_id": "uuid-456",
      "customer_id": 456,
      "approved": false,
      "skip_reason": "low_intent"
    }
  ],
  "total": 3,
  "approved": 1,
  "skipped": 2
}

Exemplo:

curl -X POST "https://csuite.internut.com.br/4c/decision/decide/batch/auto" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_ids": [123, 456, 789],
    "org_id": 1
  }'

Casos de uso:
- Campanhas em massa
- Processamento batch
- Automação de marketing


5. Candidatos Automáticos

Endpoint: GET /candidates/auto ou GET /v1/candidates/auto

Descrição: Obtém lista de candidatos automáticos para um cliente.

Parâmetros de Query:
- customer_id (int, obrigatório) - ID do cliente
- org_id (int, opcional) - ID da organização
- limit (int, padrão: 10) - Número máximo de candidatos

Response:

{
  "customer_id": 123,
  "candidates": [
    {
      "sku": "BK4-2516",
      "price": 1500.00,
      "score": 0.88
    },
    {
      "sku": "BK4-2517",
      "price": 2000.00,
      "score": 0.75
    }
  ]
}

Exemplo:

curl "https://csuite.internut.com.br/4c/decision/candidates/auto?customer_id=123&org_id=1&limit=10"

Casos de uso:
- Pré-visualização de ofertas
- Seleção manual de candidatos
- Análise de recomendações


6. Executar Ação

Endpoint: POST /send ou POST /v1/send

Descrição: Executa uma ação (envio de mensagem) baseada em uma decisão.

Request:

{
  "decision_id": "uuid-123",
  "action": {
    "type": "whatsapp",
    "customer_id": 123,
    "message": "Olá! Temos uma oferta especial para você...",
    "offer": {
      "sku": "BK4-2516",
      "price": 1500.00
    }
  }
}

Parâmetros:
- decision_id (string, obrigatório) - ID da decisão (retornado por /decide)
- action (object, obrigatório) - Ação a ser executada
- type (string) - Tipo de ação: whatsapp, email, crm, etc.
- customer_id (int) - ID do cliente
- message (string) - Mensagem a ser enviada
- offer (object, opcional) - Oferta associada

Response:

{
  "decision_id": "uuid-123",
  "status": "queued",
  "action_id": "action-uuid",
  "queued_at": "2025-01-27T14:30:00Z"
}

Exemplo:

curl -X POST "https://csuite.internut.com.br/4c/decision/send" \
  -H "Content-Type: application/json" \
  -d '{
    "decision_id": "uuid-123",
    "action": {
      "type": "whatsapp",
      "customer_id": 123,
      "message": "Oferta especial para você!"
    }
  }'

Casos de uso:
- Executar decisão aprovada
- Envio de mensagens
- Integração com sistemas externos


7. Versionamento

Todos os endpoints possuem versão /v1/...:

Recomendação: Use preferencialmente as versões /v1/... para garantir compatibilidade futura.


8. Health & Metrics

Health Check

Endpoint: GET /health

Descrição: Verifica saúde da API.

Response:

{
  "status": "ok"
}

Exemplo:

curl "https://csuite.internut.com.br/4c/decision/health"

Métricas Prometheus

Endpoint: GET /metrics

Descrição: Retorna métricas Prometheus da Decision API.

Exemplo:

curl "https://csuite.internut.com.br/4c/decision/metrics"

Telemetria

Endpoint: GET /telemetry/events/count

Descrição: Retorna contagem de eventos em ClickHouse.

Parâmetros de Query:
- since_minutes (int, padrão: 60) - Janela de tempo em minutos

Exemplo:

curl "https://csuite.internut.com.br/4c/decision/telemetry/events/count?since_minutes=60"

Métricas do Executor

Endpoint: GET /metrics/executor

Descrição: Proxy para expor métricas do executor via Decision API.

Exemplo:

curl "https://csuite.internut.com.br/4c/decision/metrics/executor"

9. Exemplos Práticos

Fluxo Completo: Decisão → Execução

import requests

BASE_URL = "https://csuite.internut.com.br/4c/decision"

# 1. Solicitar decisão
decision_resp = requests.post(
    f"{BASE_URL}/v1/decide",
    json={
        "customer_id": 123,
        "org_id": 1,
        "candidates": [
            {"sku": "BK4-2516", "price": 1500.00}
        ],
        "include_explanations": True
    }
)
decision = decision_resp.json()

# 2. Se aprovada, executar ação
if decision.get("approved"):
    send_resp = requests.post(
        f"{BASE_URL}/v1/send",
        json={
            "decision_id": decision["decision_id"],
            "action": {
                "type": decision["channel"],
                "customer_id": 123,
                "message": f"Oferta especial: {decision['offer']['sku']} por R$ {decision['offer']['price']:.2f}",
                "offer": decision["offer"]
            }
        }
    )
    print(f"Ação enviada: {send_resp.json()}")
else:
    print(f"Decisão pulada: {decision.get('skip_reason')}")

Decisão Automática em Lote

import requests

BASE_URL = "https://csuite.internut.com.br/4c/decision"

# Obter lista de clientes
customer_ids = [123, 456, 789, 101, 102]

# Decisões em lote
batch_resp = requests.post(
    f"{BASE_URL}/v1/decide/batch/auto",
    json={
        "customer_ids": customer_ids,
        "org_id": 1
    }
)
batch_result = batch_resp.json()

print(f"Total: {batch_result['total']}")
print(f"Aprovadas: {batch_result['approved']}")
print(f"Puladas: {batch_result['skipped']}")

# Executar ações para decisões aprovadas
for decision in batch_result["decisions"]:
    if decision.get("approved"):
        requests.post(
            f"{BASE_URL}/v1/send",
            json={
                "decision_id": decision["decision_id"],
                "action": {
                    "type": decision["channel"],
                    "customer_id": decision["customer_id"],
                    "message": f"Oferta: {decision['offer']['sku']}",
                    "offer": decision["offer"]
                }
            }
        )

Obter Candidatos e Decidir

import requests

BASE_URL = "https://csuite.internut.com.br/4c/decision"

# 1. Obter candidatos automáticos
candidates_resp = requests.get(
    f"{BASE_URL}/v1/candidates/auto",
    params={"customer_id": 123, "org_id": 1, "limit": 5}
)
candidates = candidates_resp.json()["candidates"]

# 2. Usar candidatos na decisão
decision_resp = requests.post(
    f"{BASE_URL}/v1/decide",
    json={
        "customer_id": 123,
        "org_id": 1,
        "candidates": [
            {"sku": c["sku"], "price": c["price"]}
            for c in candidates
        ],
        "include_explanations": True
    }
)
decision = decision_resp.json()

10. Troubleshooting

Erro 500 (Internal Server Error)

Possíveis causas:
- Serviço Feature Service indisponível
- Serviço Scoring Service indisponível
- Erro de conexão com MySQL/ClickHouse
- Erro no Policy Engine

Solução:
1. Verificar logs em Grafana/Kibana
2. Verificar saúde dos serviços (/health)
3. Verificar conexão com banco de dados
4. Verificar configuração de variáveis de ambiente

Erro 404 (Not Found)

Possíveis causas:
- Endpoint incorreto
- Roteamento Traefik incorreto
- Serviço não está rodando

Solução:
1. Verificar URL base: https://csuite.internut.com.br/4c/decision
2. Verificar roteamento no Traefik
3. Verificar se o serviço está rodando: docker service ls

Erro 429 (Too Many Requests)

Possíveis causas:
- Rate limiting ativado
- Muitas requisições por minuto

Solução:
1. Verificar limites configurados:
- RATE_LIMIT_DECIDE_RPM (padrão: 120)
- RATE_LIMIT_SEND_RPM (padrão: 240)
2. Reduzir frequência de requisições
3. Usar batch endpoints para múltiplos clientes

Timeout

Possíveis causas:
- Latência alta nos serviços
- Timeout de conexão com banco de dados
- Cache Redis indisponível

Solução:
1. Verificar latência dos serviços
2. Verificar conexão com MySQL/Redis
3. Verificar cache do Redis
4. Aumentar timeout se necessário

Decisão Sempre Pulada

Possíveis causas:
- Score de intenção muito baixo
- Constraints muito restritivos
- Cliente em opt-out
- Políticas do CSuite bloqueando

Solução:
1. Verificar skip_reason na resposta
2. Verificar scores retornados
3. Ajustar constraints ou políticas
4. Verificar opt-out do cliente


📚 Documentação Adicional


🔐 Autenticação

Por padrão, a API não requer autenticação. Para produção, configure:


📊 Rate Limiting

A Decision API implementa rate limiting leve em memória, por IP + endpoint, configurável por variáveis de ambiente:

Nota: Este mecanismo é uma proteção básica (anti-abuso acidental). Para ambientes de alta escala, recomenda-se combiná-lo com rate limiting em camada de borda (Traefik, Nginx, API Gateway).


Última atualização: 2025-01-27

🔊 Text-to-Speech

1.0x
1.0
Pronto para reproduzir