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:
{
"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:
{
"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:
{
"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_REQUEST—ipIdinválido404 NOT_FOUND— IP não existe429 REPUTATION_RATE_LIMITED— >5 verificacoes/min502 REPUTATION_NOT_AVAILABLE— a verificação no provedor falhou503 REPUTATION_NOT_AVAILABLE— serviço de reputacao não configurado503 SERVICE_UNAVAILABLE,500 INTERNAL