Network Graph Api¶
Autor: Anderson Henrique da Silva Localização: Minas Gerais, Brasil Última Atualização: 2025-10-13 15:15:18 -0300
🕸️ API de Grafos de Relacionamento - Guia para Frontend¶
Sistema de análise de rede cross-investigation para detecção de padrões suspeitos
📋 Índice¶
- Visão Geral
- Endpoints Principais
- Modelos de Dados
- Exemplos de Uso
- Visualizações
- Integração Automática
🎯 Visão Geral¶
O sistema de grafos conecta empresas, pessoas e órgãos públicos através de investigações, criando uma rede persistente de relacionamentos que permite:
- ✅ Análise cross-investigation: Ver histórico completo de uma entidade
- ✅ Detecção de redes suspeitas: Cartéis, laranjas, concentração
- ✅ Visualização de relacionamentos: Grafos interativos D3.js/Cytoscape
- ✅ Métricas de rede: Centralidade, influência, pontes
- ✅ Relatórios enriquecidos: Insights baseados em investigações anteriores
🔗 Endpoints Principais¶
1. Buscar Entidades¶
Parâmetros:
- query (string): Nome, CNPJ ou CPF (mínimo 3 caracteres)
- entity_type (opcional): empresa, pessoa_fisica, orgao_publico
- limit (int): Máximo de resultados (padrão: 20, max: 100)
Resposta:
[
{
"id": "uuid-entidade",
"entity_type": "empresa",
"name": "Construtora XYZ LTDA",
"cnpj": "12.345.678/0001-90",
"total_investigations": 5,
"total_contracts": 12,
"total_contract_value": 1500000.50,
"risk_score": 7.3,
"is_sanctioned": true
}
]
2. Obter Rede de uma Entidade¶
Parâmetros:
- depth (int): Profundidade da rede (1-3 níveis)
Resposta:
{
"nodes": [
{
"id": "uuid-1",
"name": "Construtora ABC",
"entity_type": "empresa",
"risk_score": 7.5,
"total_investigations": 3
},
{
"id": "uuid-2",
"name": "João Silva",
"entity_type": "pessoa_fisica",
"risk_score": 5.2,
"total_investigations": 2
}
],
"edges": [
{
"id": "rel-uuid",
"source": "uuid-1",
"target": "uuid-2",
"relationship_type": "owns",
"strength": 0.9,
"is_suspicious": false
}
],
"node_count": 15,
"edge_count": 20
}
3. Visualização Cytoscape.js¶
Retorna JSON pronto para Cytoscape.js:
{
"elements": {
"nodes": [
{
"data": {
"id": "uuid-1",
"label": "Empresa ABC",
"type": "empresa",
"risk_score": 7.5
}
}
],
"edges": [
{
"data": {
"id": "rel-1",
"source": "uuid-1",
"target": "uuid-2",
"label": "owns",
"strength": 0.9
}
}
]
},
"layout": {
"name": "cose",
"animate": true
},
"style": [
{
"selector": "node",
"style": {
"label": "data(label)",
"background-color": "#009B3A"
}
}
]
}
4. Visualização D3.js Force Graph¶
Retorna JSON para D3.js:
{
"nodes": [
{
"id": "uuid-1",
"name": "Empresa ABC",
"type": "empresa",
"risk_score": 7.5,
"radius": 10
}
],
"links": [
{
"source": "uuid-1",
"target": "uuid-2",
"type": "owns",
"strength": 0.9,
"value": 9
}
]
}
5. Redes Suspeitas Detectadas¶
Parâmetros:
- network_type: cartel, shell_network, concentration, fraud_ring, collusion
- severity: low, medium, high, critical
- active_only (bool): Apenas redes ativas (padrão: true)
Resposta:
[
{
"id": "network-uuid",
"network_name": "Possível Cartel - Agência 12345",
"network_type": "cartel",
"entity_count": 5,
"detection_reason": "5 fornecedores concentrados contratando com mesma agência",
"confidence_score": 0.85,
"severity": "high",
"total_contract_value": 2500000.00,
"suspicious_value": 500000.00,
"investigation_ids": ["inv-1", "inv-2"],
"is_active": true,
"reviewed": false
}
]
6. Investigações de uma Entidade¶
Resposta:
[
{
"id": "ref-uuid",
"investigation_id": "inv-uuid",
"role": "supplier",
"contract_id": "contract-123",
"contract_value": 150000.00,
"involved_in_anomalies": true,
"anomaly_ids": ["anomaly-1", "anomaly-2"],
"detected_at": "2025-10-01T10:30:00Z"
}
]
7. Estatísticas Gerais¶
Resposta:
{
"total_entities": 1523,
"total_relationships": 3456,
"total_suspicious_networks": 12,
"entity_types": {
"empresa": 890,
"pessoa_fisica": 423,
"orgao_publico": 210
},
"top_entities_by_centrality": [
{
"id": "uuid",
"name": "Empresa ABC",
"entity_type": "empresa",
"degree_centrality": 25,
"total_investigations": 8
}
],
"recent_suspicious_networks": [
{
"id": "net-uuid",
"network_name": "Cartel XYZ",
"network_type": "cartel",
"severity": "critical",
"entity_count": 7
}
]
}
8. Revisar Rede Suspeita (Admin)¶
Body:
Resposta:
{
"status": "reviewed",
"network_id": "net-uuid",
"message": "Rede suspeita marcada como revisada com sucesso"
}
📊 Modelos de Dados¶
EntityNode (Entidade)¶
interface EntityNode {
id: string;
entity_type: 'empresa' | 'pessoa_fisica' | 'orgao_publico';
name: string;
cnpj?: string;
cpf?: string;
agency_code?: string;
statistics: {
total_investigations: number;
total_contracts: number;
total_contract_value: number;
total_anomalies: number;
};
risk_score: number; // 0-10
is_sanctioned: boolean;
sanction_details: object;
network_metrics: {
degree_centrality: number;
betweenness_centrality: number;
closeness_centrality: number;
eigenvector_centrality: number;
};
}
EntityRelationship (Relacionamento)¶
interface EntityRelationship {
id: string;
source_entity_id: string;
target_entity_id: string;
relationship_type: 'owns' | 'manages' | 'contracts_with' | 'partners_with' | 'employs';
strength: number; // 0-1
confidence: number; // 0-1
detection_count: number;
investigation_ids: string[];
evidence: object;
is_suspicious: boolean;
suspicion_reasons: string[];
}
SuspiciousNetwork (Rede Suspeita)¶
interface SuspiciousNetwork {
id: string;
network_name: string;
network_type: 'cartel' | 'shell_network' | 'concentration' | 'fraud_ring' | 'collusion';
entity_ids: string[];
entity_count: number;
detection_reason: string;
confidence_score: number; // 0-1
severity: 'low' | 'medium' | 'high' | 'critical';
financial_impact: {
total_contract_value: number;
suspicious_value: number;
};
investigation_ids: string[];
is_active: boolean;
reviewed: boolean;
review_notes?: string;
graph_data: object; // Dados para visualização
}
💡 Exemplos de Uso¶
Exemplo 1: Buscar e Visualizar Rede¶
// 1. Buscar entidade
const response = await fetch('/api/v1/network/entities/search?query=Construtora ABC');
const entities = await response.json();
const entity = entities[0];
// 2. Obter rede da entidade
const networkResponse = await fetch(`/api/v1/network/entities/${entity.id}/network?depth=2`);
const networkData = await networkResponse.json();
// 3. Visualizar com D3.js
const d3Data = await fetch(`/api/v1/network/export/d3/${entity.id}?depth=2`).then(r => r.json());
// Renderizar grafo D3
const svg = d3.select('#graph');
const simulation = d3.forceSimulation(d3Data.nodes)
.force('link', d3.forceLink(d3Data.links).id(d => d.id))
.force('charge', d3.forceManyBody())
.force('center', d3.forceCenter(width / 2, height / 2));
Exemplo 2: Listar Redes Suspeitas¶
const suspiciousResponse = await fetch('/api/v1/network/suspicious-networks?severity=high&active_only=true');
const networks = await suspiciousResponse.json();
// Exibir alertas
networks.forEach(net => {
if (net.severity === 'critical') {
showAlert(`🚨 ${net.network_name}: ${net.detection_reason}`);
}
});
Exemplo 3: Ver Histórico de Entidade¶
const entityId = 'uuid-da-entidade';
// Detalhes completos
const entity = await fetch(`/api/v1/network/entities/${entityId}`).then(r => r.json());
// Todas as investigações
const investigations = await fetch(`/api/v1/network/entities/${entityId}/investigations`).then(r => r.json());
// Exibir linha do tempo
investigations.sort((a, b) => new Date(a.detected_at) - new Date(b.detected_at));
🎨 Visualizações Recomendadas¶
Opção 1: Cytoscape.js (Recomendado)¶
<div id="cy" style="width: 100%; height: 600px;"></div>
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<script>
fetch(`/api/v1/network/export/cytoscape/${entityId}?depth=2`)
.then(r => r.json())
.then(data => {
const cy = cytoscape({
container: document.getElementById('cy'),
elements: data.elements,
style: data.style,
layout: data.layout
});
});
</script>
Opção 2: D3.js Force Graph¶
const d3Data = await fetch(`/api/v1/network/export/d3/${entityId}?depth=2`).then(r => r.json());
const svg = d3.select('#graph')
.attr('width', width)
.attr('height', height);
const simulation = d3.forceSimulation(d3Data.nodes)
.force('link', d3.forceLink(d3Data.links).id(d => d.id).distance(100))
.force('charge', d3.forceManyBody().strength(-300))
.force('center', d3.forceCenter(width / 2, height / 2));
// Renderizar nós e arestas...
Opção 3: React Flow (Moderno)¶
import ReactFlow from 'reactflow';
const NetworkGraph = ({ entityId }) => {
const [nodes, setNodes] = useState([]);
const [edges, setEdges] = useState([]);
useEffect(() => {
fetch(`/api/v1/network/entities/${entityId}/network?depth=2`)
.then(r => r.json())
.then(data => {
const flowNodes = data.nodes.map(n => ({
id: n.id,
data: { label: n.name },
position: { x: Math.random() * 500, y: Math.random() * 500 }
}));
const flowEdges = data.edges.map(e => ({
id: e.id,
source: e.source,
target: e.target,
label: e.type
}));
setNodes(flowNodes);
setEdges(flowEdges);
});
}, [entityId]);
return <ReactFlow nodes={nodes} edges={edges} />;
};
🤖 Integração Automática¶
O sistema constrói grafos automaticamente após cada investigação:
Fluxo Automático:¶
Investigação Concluída
↓
Extração de Entidades
↓
Criação/Atualização de Nós no Grafo
↓
Criação de Relacionamentos
↓
Cálculo de Métricas de Rede
↓
Detecção de Redes Suspeitas
↓
Enriquecimento de Relatórios
Dados Enriquecidos em Relatórios:¶
Quando uma entidade é encontrada em múltiplas investigações, o relatório inclui:
{
"anomaly_id": "...",
"network_analysis": [
{
"entity_name": "Construtora XYZ",
"historical_data": {
"total_investigations": 5,
"total_contracts": 12,
"total_contract_value": 1500000.00,
"risk_score": 7.3,
"is_sanctioned": true
},
"network_metrics": {
"degree_centrality": 15,
"betweenness_centrality": 0.65
},
"connections": {
"node_count": 8,
"immediate_connections": [
{"name": "João Silva", "type": "pessoa_fisica"},
{"name": "Agência ABC", "type": "orgao_publico"}
]
}
}
],
"cross_investigation_insights": [
"⚠️ **Entidade Recorrente**: Construtora XYZ aparece em 5 investigações anteriores, totalizando R$ 1.500.000,00 em contratos.",
"🚨 **Alto Risco**: Construtora XYZ tem score de risco 7.3/10, indicando histórico de irregularidades.",
"🕸️ **Altamente Conectada**: Construtora XYZ possui 15 conexões diretas, indicando posição central na rede."
]
}
🔐 Permissões¶
- GET endpoints: Qualquer usuário autenticado
- POST /review: Apenas administradores
- Network metrics: Calculados automaticamente pelo sistema
📈 Métricas de Rede Explicadas¶
| Métrica | O que Significa | Uso no Frontend |
|---|---|---|
| Degree Centrality | Número de conexões diretas | Tamanho do nó no grafo |
| Betweenness Centrality | Ponte entre redes | Cor especial (intermediário) |
| Closeness Centrality | Proximidade média | Posição no layout |
| Eigenvector Centrality | Influência (baseada em conexões influentes) | Destaque visual |
🎯 Casos de Uso para Frontend¶
Dashboard Principal¶
- Mostrar estatísticas gerais (
/network/statistics) - Listar redes suspeitas ativas
- Top entidades por centralidade
Página de Investigação¶
- Grafo de entidades da investigação específica
- Insights cross-investigation
- Links para entidades relacionadas
Página de Entidade¶
- Detalhes completos da entidade
- Rede de relacionamentos interativa (Cytoscape/D3)
- Lista de todas as investigações envolvendo a entidade
- Timeline de atividades
Página de Redes Suspeitas¶
- Lista filtrada de redes
- Visualização do grafo de cada rede
- Ferramenta de revisão para investigadores
🚀 Deploy¶
Migration do Banco:¶
Registrar Rotas no App:¶
📞 Suporte¶
Para questões sobre a API de grafos:
- Documentação Swagger: /docs#/Network%20Analysis
- Exemplos completos: Ver seção "Exemplos de Uso" acima
🇧🇷 Feito com 💚 para investigadores brasileiros 💛