2 Validador de Reputacao de IP (Superadmin)

17.Y2 Validador de Reputacao de IP (Superadmin)#

Surface read-only (Phase 1) que cruza os campos reputation_* de proxy_ips com a tabela de histórico proxy_ip_reputation_checks. O loop periodico verifica a reputacao de cada IP do pool contra provedores externos (IPQS, etc.); estes endpoints expoem o estado e permitem uma verificação sob demanda.

Endpoint base: /v1/admin/reputation/*. Todos requerem JWT de superadmin.

GET/v1/admin/reputation/ip/{ipId}#

Snapshot atual de um IP + a verificação mais recente (com signals + breakdown completos). 404 se a linha proxy_ips não existe.

Auth: Superadmin

Resposta 200:

json
{
  "proxy_ip_id": 7,
  "ip_address": "200.160.45.35",
  "snapshot": {
    "score": 100,
    "status": "ok",
    "checked_at": "2026-05-04T00:00:00Z",
    "provider_count": 2,
    "summary": ""
  },
  "latest_check": {
    "id": 55,
    "trigger_kind": "periodic",
    "score": 100,
    "status": "ok",
    "duration_ms": 2400,
    "provider_count": 2,
    "reason": "",
    "signals": [],
    "breakdown": [],
    "created_at": "2026-05-04T00:00:00Z"
  }
}

latest_check e null quando o IP nunca teve uma verificação registrada.

Erros: 400 BAD_REQUEST (id inválido), 404 NOT_FOUND (IP não existe), 503 SERVICE_UNAVAILABLE, 500 INTERNAL.

GET/v1/admin/reputation/ip/{ipId}/history#

Últimas N verificacoes de um IP, mais recentes primeiro (projecao leve, sem signals/breakdown).

Auth: Superadmin Query: limit (default 50, max 200)

Resposta 200:

json
{
  "proxy_ip_id": 7,
  "items": [
    {
      "id": 55, "trigger_kind": "periodic", "score": 100,
      "status": "ok", "duration_ms": 2400, "provider_count": 2,
      "reason": "", "created_at": "2026-05-04T00:00:00Z"
    }
  ],
  "limit": 50,
  "total_returned": 1
}

Erros: 400 BAD_REQUEST, 503 SERVICE_UNAVAILABLE, 500 INTERNAL.

GET/v1/admin/reputation/summary#

Agregados pool-wide. Conta apenas IPs vivos (exclui decommissioned).

Auth: Superadmin

Resposta 200:

json
{
  "pool_total": 12,
  "by_status": { "ok": 10, "watch": 1, "bad": 0, "inconclusive": 1, "unknown": 0 },
  "median_score": 100,
  "watch_count": 1,
  "bad_count": 0,
  "coverage_pct": 92,
  "checks_total_30d": 340
}

coverage_pct e a fracao de IPs com snapshot atualizado nos últimos 7 dias; abaixo de 80% indica que o loop periodico está atrasado.

Erros: 503 SERVICE_UNAVAILABLE, 500 INTERNAL.

POST/v1/admin/reputation/check/{ipId}#

Roda uma verificação de reputacao sob demanda para o IP. Ignora o filtro de TTL do loop periodico. Persiste o veredito com trigger_kind="on_demand".

Auth: Superadmin

Rate-limited em 5 verificacoes por minuto por superadmin (429 REPUTATION_RATE_LIMITED + header Retry-After: 60).

Body: nenhum.

Resposta 200: mesmo envelope de GET /v1/admin/reputation/ip/{ipId} (proxy_ip_id, ip_address, snapshot, latest_check). Quando a persistencia falha mas o veredito e válido, retorna { "warning": "verdict_persist_failed: ...", "score": N, "status": "...", "reason": "..." }.

Erros:

  • 400 BAD_REQUESTipId inválido
  • 404 NOT_FOUND — IP não existe
  • 429 REPUTATION_RATE_LIMITED — >5 verificacoes/min
  • 502 REPUTATION_NOT_AVAILABLE — a verificação no provedor falhou
  • 503 REPUTATION_NOT_AVAILABLE — serviço de reputacao não configurado
  • 503 SERVICE_UNAVAILABLE, 500 INTERNAL