Análise de Agravos
Guia completo para registro, acompanhamento e análise de agravos de saúde
Este guia detalha como usar o módulo de Agravos do Sinapse para gerenciar notificações de doenças e agravos de saúde pública, incluindo registro de casos, acompanhamento, geração de relatórios e análise epidemiológica.
Objetivos
Ao final deste guia, você será capaz de:
- Registrar novos casos de agravos
- Acompanhar a evolução dos casos
- Gerar relatórios e estatísticas
- Analisar dados epidemiológicos
- Integrar com outros sistemas de saúde
Pré-requisitos
Conta ativa no Sinapse
Permissão agravos.listar para visualizar
Permissão agravos.criar para registrar casos
Token de autenticação válido
Conhecimento dos códigos CID-10 (opcional)
Agravos Disponíveis
O sistema atualmente suporta os seguintes agravos de notificação obrigatória:
Dengue
- CID-10: A90, A91
- Exames: NS1, IgM, IgG
- Evolução: 14 dias
Zika Vírus
- CID-10: A92.8
- Exames: RT-PCR, IgM
- Atenção: Gestantes
Chikungunya
- CID-10: A92.0
- Exames: RT-PCR, IgM, IgG
- Fase crônica: >90 dias
Workflow 1: Listar e Filtrar Casos
Passo 1: Listar Tipos de Agravos
Primeiro, veja quais tipos estão disponíveis:
curl -X GET https://api.sinapse.org.br/v1/agravos/tipos \
-H "Authorization: Bearer SEU_TOKEN"Passo 2: Buscar Casos com Filtros
# Casos de dengue em São Paulo nos últimos 30 dias
curl -X GET "https://api.sinapse.org.br/v1/agravos/casos?\
agravo_codigo=dengue&\
estado_residencia=SP&\
data_inicio=2025-06-29&\
data_fim=2025-07-29&\
page=1&size=50" \
-H "Authorization: Bearer SEU_TOKEN"import requests
from datetime import datetime, timedelta
# Configuração
base_url = "https://api.sinapse.org.br/v1"
headers = {"Authorization": f"Bearer {token}"}
# Filtros
data_fim = datetime.now().date()
data_inicio = data_fim - timedelta(days=30)
params = {
"agravo_codigo": "dengue",
"estado_residencia": "SP",
"data_inicio": data_inicio.isoformat(),
"data_fim": data_fim.isoformat(),
"page": 1,
"size": 50
}
# Requisição
response = requests.get(
f"{base_url}/agravos/casos",
headers=headers,
params=params
)
if response.status_code == 200:
dados = response.json()
print(f"Total de casos: {dados['total']}")
for caso in dados['items']:
print(f"\nCaso: {caso['numero_notificacao']}")
print(f"Município: {caso['municipio_residencia']}")
print(f"Classificação: {caso['classificacao_final']}")async function buscarCasosDengue() {
const baseUrl = 'https://api.sinapse.org.br/v1';
const token = localStorage.getItem('access_token');
// Calcular datas
const dataFim = new Date();
const dataInicio = new Date();
dataInicio.setDate(dataInicio.getDate() - 30);
// Parâmetros
const params = new URLSearchParams({
agravo_codigo: 'dengue',
estado_residencia: 'SP',
data_inicio: dataInicio.toISOString().split('T')[0],
data_fim: dataFim.toISOString().split('T')[0],
page: 1,
size: 50
});
try {
const response = await fetch(
`${baseUrl}/agravos/casos?${params}`,
{
headers: {
'Authorization': `Bearer ${token}`
}
}
);
if (response.ok) {
const dados = await response.json();
console.log(`Total de casos: ${dados.total}`);
dados.items.forEach(caso => {
console.log(`Caso: ${caso.numero_notificacao}`);
console.log(`Município: ${caso.municipio_residencia}`);
});
}
} catch (error) {
console.error('Erro ao buscar casos:', error);
}
}Passo 3: Aplicar Filtros Avançados
Você pode combinar múltiplos filtros:
- Por período:
data_inicioedata_fim - Por localização:
municipio_residencia,estado_residencia - Por classificação:
classificacao_final(confirmado, suspeito, descartado) - Por evolução:
evolucao(alta, obito, em_acompanhamento)
Workflow 2: Registrar Novo Caso
Passo 1: Preparar Dados do Caso
Notificação Oportuna: Registre casos suspeitos imediatamente, sem aguardar confirmação laboratorial.
Passo 2: Criar Notificação
// Formulário de notificação
const novoCaso = {
// Identificação do agravo
agravo_codigo: "dengue",
numero_notificacao: gerarNumeroNotificacao(),
// Dados do paciente
paciente_nome: "João Silva",
paciente_idade: 35,
paciente_sexo: "M",
// Localização
municipio_residencia: "São Paulo",
estado_residencia: "SP",
bairro: "Vila Mariana",
// Dados clínicos
data_primeiros_sintomas: "2025-07-25",
data_notificacao: new Date().toISOString(),
// Sintomas (específicos para dengue)
sintomas: {
febre: true,
cefaleia: true,
mialgia: true,
artralgia: false,
exantema: false,
prurido: false,
nausea: true,
vomito: false,
dor_retro_orbital: true
},
// Dados específicos do agravo
dados_especificos: {
classificacao_inicial: "dengue_classico",
sinais_alarme: false,
prova_laco: "nao_realizada",
comorbidades: ["hipertensao", "diabetes"],
hospitalizacao: false
}
};
// Função auxiliar
function gerarNumeroNotificacao() {
const ano = new Date().getFullYear();
const random = Math.floor(Math.random() * 999999);
return `${ano}-${String(random).padStart(6, '0')}`;
}curl -X POST https://api.sinapse.org.br/v1/agravos/casos \
-H "Authorization: Bearer SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"agravo_codigo": "dengue",
"numero_notificacao": "2025-001234",
"paciente_nome": "João Silva",
"paciente_idade": 35,
"paciente_sexo": "M",
"municipio_residencia": "São Paulo",
"estado_residencia": "SP",
"data_primeiros_sintomas": "2025-07-25",
"sintomas": {
"febre": true,
"cefaleia": true,
"mialgia": true
},
"dados_especificos": {
"classificacao_inicial": "dengue_classico",
"sinais_alarme": false
}
}'Passo 3: Validar Resposta
{
"id": 12345,
"numero_notificacao": "2025-001234",
"status": "em_investigacao",
"mensagem": "Caso registrado com sucesso",
"proximos_passos": [
"Aguardar resultados laboratoriais",
"Atualizar classificação quando disponível",
"Monitorar evolução do paciente"
]
}Workflow 3: Acompanhar Evolução
Passo 1: Adicionar Resultado de Exame
def atualizar_com_exame(caso_id: int, resultado_exame: dict):
"""Atualiza caso com resultado de exame laboratorial"""
dados_atualizacao = {
"exames": [{
"tipo": "NS1",
"resultado": "reagente",
"data_coleta": "2025-07-26",
"data_resultado": "2025-07-27",
"laboratorio": "LACEN-SP"
}],
"classificacao_final": determinar_classificacao(resultado_exame),
"confirmacao_laboratorial": True
}
response = requests.put(
f"{base_url}/agravos/casos/{caso_id}",
headers=headers,
json=dados_atualizacao
)
return response.json()
def determinar_classificacao(exame):
"""Determina classificação baseada no exame"""
if exame["resultado"] == "reagente":
return "confirmado_laboratorial"
elif exame["resultado"] == "nao_reagente":
return "descartado"
else:
return "inconclusivo"Passo 2: Registrar Evolução
async function registrarEvolucao(casoId, evolucao) {
const atualizacao = {
evolucao: evolucao.status, // "alta", "obito", "transferencia"
data_evolucao: new Date().toISOString(),
observacoes: evolucao.observacoes,
// Se óbito
...(evolucao.status === 'obito' && {
data_obito: evolucao.dataObito,
causa_obito: evolucao.causaObito
}),
// Se alta
...(evolucao.status === 'alta' && {
sequelas: evolucao.sequelas || false,
descricao_sequelas: evolucao.descricaoSequelas
})
};
const response = await fetch(
`${baseUrl}/agravos/casos/${casoId}`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(atualizacao)
}
);
return response.json();
}Workflow 4: Análise e Estatísticas
Passo 1: Obter Estatísticas Agregadas
def analisar_surto(municipio: str, dias: int = 30):
"""Analisa possível surto em município"""
# Buscar estatísticas
params = {
"municipio": municipio,
"agregacao": "dia",
"metricas": "casos,confirmados,incidencia",
"dias": dias
}
response = requests.get(
f"{base_url}/agravos/casos/estatisticas",
headers=headers,
params=params
)
stats = response.json()
# Análise simples de tendência
serie_temporal = stats["serie_temporal"]
casos_recentes = sum(dia["casos_novos"] for dia in serie_temporal[-7:])
casos_anteriores = sum(dia["casos_novos"] for dia in serie_temporal[-14:-7])
if casos_recentes > casos_anteriores * 1.5:
print(f"ALERTA: Aumento de {((casos_recentes/casos_anteriores)-1)*100:.1f}% nos casos")
print(f"Última semana: {casos_recentes} casos")
print(f"Semana anterior: {casos_anteriores} casos")
return statsPasso 2: Gerar Mapa de Calor
// Integração com Leaflet para visualização
async function gerarMapaCalor(estado, tipoAgravo) {
const response = await fetch(
`${baseUrl}/agravos/casos/mapa-calor?` +
`estado=${estado}&tipo_agravo=${tipoAgravo}&periodo=30`,
{ headers: { 'Authorization': `Bearer ${token}` } }
);
const geoJson = await response.json();
// Criar mapa
const map = L.map('mapa').setView([-23.5505, -46.6333], 10);
// Adicionar camada de calor
const heatData = geoJson.features.map(feature => [
feature.geometry.coordinates[1], // latitude
feature.geometry.coordinates[0], // longitude
feature.properties.intensidade // peso
]);
L.heatLayer(heatData, {
radius: 25,
blur: 15,
maxZoom: 17,
gradient: {
0.4: 'blue',
0.6: 'yellow',
0.8: 'orange',
1.0: 'red'
}
}).addTo(map);
return map;
}Passo 3: Dashboard de Monitoramento
class DashboardAgravos:
def __init__(self, api_client):
self.api = api_client
async def gerar_resumo_executivo(self, periodo_dias=7):
"""Gera resumo executivo para gestores"""
# Coletar dados
stats = await self.api.get_estatisticas(dias=periodo_dias)
casos_por_tipo = await self.api.get_casos_por_tipo()
municipios_criticos = await self.api.get_municipios_criticos()
resumo = {
"periodo": f"Últimos {periodo_dias} dias",
"total_notificacoes": stats["total_casos"],
"casos_confirmados": stats["confirmados"],
"taxa_confirmacao": stats["confirmados"] / stats["total_casos"] * 100,
"distribuicao_agravos": {
tipo: {
"casos": dados["total"],
"percentual": dados["total"] / stats["total_casos"] * 100,
"tendencia": self._calcular_tendencia(dados["serie"])
}
for tipo, dados in casos_por_tipo.items()
},
"alertas": [],
"recomendacoes": []
}
# Gerar alertas
for municipio in municipios_criticos:
if municipio["taxa_crescimento"] > 50:
resumo["alertas"].append({
"tipo": "surto_potencial",
"municipio": municipio["nome"],
"crescimento": f"{municipio['taxa_crescimento']}%",
"acao_recomendada": "Investigação epidemiológica urgente"
})
return resumo
def _calcular_tendencia(self, serie):
"""Calcula se tendência é crescente, estável ou decrescente"""
if len(serie) < 2:
return "indefinida"
primeira_metade = sum(serie[:len(serie)//2])
segunda_metade = sum(serie[len(serie)//2:])
if segunda_metade > primeira_metade * 1.2:
return "crescente"
elif segunda_metade < primeira_metade * 0.8:
return "decrescente"
else:
return "estável"Workflow 5: Exportação e Integração
Exportar Dados para Análise
def exportar_para_analise(filtros: dict, formato: str = "csv"):
"""Exporta dados para análise externa"""
# Endpoint de exportação
response = requests.post(
f"{base_url}/agravos/casos/exportar",
headers=headers,
json={
"filtros": filtros,
"formato": formato,
"campos": [
"numero_notificacao",
"agravo_codigo",
"data_notificacao",
"municipio_residencia",
"classificacao_final",
"evolucao"
]
}
)
if response.status_code == 202:
# Exportação assíncrona
job_id = response.json()["job_id"]
return aguardar_exportacao(job_id)
return response.contentIntegração com SINAN
// Preparar dados para envio ao SINAN
function prepararParaSINAN(caso) {
return {
NU_NOTIFIC: caso.numero_notificacao,
ID_AGRAVO: mapearCID10ParaSINAN(caso.agravo.cid10_codes[0]),
DT_NOTIFIC: formatarDataSINAN(caso.data_notificacao),
ID_MUNICIP: caso.codigo_ibge_municipio,
// Dados do paciente (anonimizados se necessário)
NM_PACIENT: caso.paciente_nome,
NU_IDADE_N: caso.paciente_idade,
CS_SEXO: caso.paciente_sexo,
// Dados clínicos
DT_SIN_PRI: formatarDataSINAN(caso.data_primeiros_sintomas),
CLASSI_FIN: mapearClassificacaoSINAN(caso.classificacao_final),
EVOLUCAO: mapearEvolucaoSINAN(caso.evolucao),
// Campos específicos por agravo
...mapearCamposEspecificos(caso)
};
}Boas Práticas de Segurança
Privacidade: Dados de pacientes são confidenciais. Use apenas para fins epidemiológicos e siga as normas da LGPD.
Anonimização de Dados
def anonimizar_exportacao(dados: list) -> list:
"""Remove dados pessoais identificáveis"""
campos_sensiveis = ['paciente_nome', 'cpf', 'endereco_completo']
for registro in dados:
for campo in campos_sensiveis:
if campo in registro:
if campo == 'paciente_nome':
registro[campo] = f"PACIENTE_{registro['id']}"
else:
registro[campo] = "***REMOVIDO***"
# Generalizar idade
if 'paciente_idade' in registro:
idade = registro['paciente_idade']
registro['faixa_etaria'] = determinar_faixa_etaria(idade)
del registro['paciente_idade']
return dadosNotificações e Alertas
Configurar Alertas Automáticos
// Configurar webhook para alertas
async function configurarAlerta(criterios) {
const config = {
nome: "Alerta Surto Dengue",
tipo_agravo: "dengue",
criterios: {
municipio: criterios.municipio,
threshold_casos: 10, // Mais de 10 casos
periodo_dias: 7, // Em 7 dias
crescimento_percentual: 50 // Ou crescimento >50%
},
notificacao: {
webhook_url: "https://seu-sistema.com/webhook/alertas",
emails: ["[email protected]"],
incluir_dados: true
}
};
const response = await fetch(
`${baseUrl}/agravos/alertas`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(config)
}
);
return response.json();
}Indicadores e KPIs
Principais Métricas
-
Taxa de Incidência
Incidência = (Casos novos / População) × 100.000 -
Taxa de Letalidade
Letalidade = (Óbitos / Casos confirmados) × 100 -
Tempo de Notificação
Tempo médio entre primeiros sintomas e notificação -
Taxa de Confirmação
Confirmação = (Casos confirmados / Total notificados) × 100
Perguntas Frequentes
Recursos Adicionais
Materiais de Referência
Suporte
- Técnico: [email protected]
- Epidemiológico: [email protected]
- Treinamento: [email protected]
Próximos Passos
API Reference - Agravos
Documentação técnica completa dos endpoints
Integração de Dados
Como integrar com outros sistemas
Exemplos de Código
Implementações prontas para usar
Parabéns! Você agora conhece todo o fluxo de trabalho com agravos no Sinapse. Use este conhecimento para melhorar a vigilância epidemiológica em sua região!