Logo

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_inicio e data_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 stats

Passo 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.content

Integraçã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 dados

Notificaçõ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

  1. Taxa de Incidência

    Incidência = (Casos novos / População) × 100.000
  2. Taxa de Letalidade

    Letalidade = (Óbitos / Casos confirmados) × 100
  3. Tempo de Notificação

    Tempo médio entre primeiros sintomas e notificação
  4. Taxa de Confirmação

    Confirmação = (Casos confirmados / Total notificados) × 100

Perguntas Frequentes

Recursos Adicionais

Materiais de Referência

Suporte

Próximos Passos


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!

On this page