Skip to content

Latest commit

 

History

1,322 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Monitor SEFAZ

Star no GitHub

License Node TypeScript CI

Status page da disponibilidade dos webservices da SEFAZ para os documentos fiscais eletrônicos brasileiros — NF-e, NFC-e, CT-e, MDF-e e DC-e, nas 27 UFs. Cruza fontes públicas por consenso, mostra o histórico de uptime num dashboard e avisa quando algo cai. Open-source, independente, sem afiliação com a SEFAZ ou a Receita Federal.

→ Acesse o monitor online

Se o monitor te ajudou, deixe uma ⭐ no repositório: é o que faz o projeto aparecer para mais gente.

Dashboard do Monitor SEFAZ

Destaques

  • 135 serviços monitorados — os 5 documentos × 27 UFs, resolvendo sozinho qual autorizador atende cada estado (próprio, SVRS, SVAN, Ambiente Nacional…).
  • Consenso multi-fonte — cruza três fontes com precedência para as oficiais, em vez de depender de uma só; se uma cai, as outras sustentam.
  • Notificações multicanal — Discord, Slack, Telegram ou webhook quando um serviço cai/volta, entra em contingência, ou sai uma Nota Técnica.
  • Detecção de drift — sinaliza quando uma fonte oficial fica inconsistente (o portal mudou o HTML), em vez de mascarar silenciosamente.
  • Zero-infra por padrão — roda como site 100% estático no GitHub Pages; sem banco, sem servidor, sem certificado.

O que ele monitora

Os cinco documentos fiscais eletrônicos, nas 27 UFs — 135 serviços no total:

  • NF-e — Nota Fiscal Eletrônica (modelo 55)
  • NFC-e — Nota Fiscal de Consumidor Eletrônica (modelo 65)
  • CT-e — Conhecimento de Transporte Eletrônico
  • MDF-e — Manifesto Eletrônico de Documentos Fiscais
  • DC-e — Declaração de Conteúdo eletrônica

Cada serviço é classificado em um de cinco estados:

Estado Significado
Operacional Serviço em operação (cStat 107).
Contingência Operando por ambiente de contingência (SVC) — ainda dá para emitir.
Instável Paralisação momentânea / lentidão (cStat 108).
Indisponível Paralisação sem previsão (cStat 109).
Sem dados Não foi possível ler o status naquele momento.

Também acompanha as Notas Técnicas publicadas no portal da NF-e, exibidas no dashboard.

Status por estado

Cada UF tem uma página com o status ao vivo dos cinco documentos, quem autoriza cada um (a própria SEFAZ, o SVRS ou o SVAN) e o que fazer quando a SEFAZ cai.

Norte Nordeste Sudeste Sul Centro-Oeste
Acre Alagoas Espírito Santo Paraná Distrito Federal
Amapá Bahia Minas Gerais Rio Grande do Sul Goiás
Amazonas Ceará Rio de Janeiro Santa Catarina Mato Grosso
Pará Maranhão São Paulo Mato Grosso do Sul
Rondônia Paraíba
Roraima Pernambuco
Tocantins Piauí
Rio Grande do Norte
Sergipe

Como obtém os dados

O modo padrão não exige certificado digital. O monitor cruza fontes públicas por consenso, com precedência para as oficiais:

  1. SVRS — portal de disponibilidade do SVRS (oficial).
  2. Receita — página de disponibilidade da NF-e/CT-e (oficial).
  3. IntegraNotas — API pública (não-oficial), mais completa.

As duas fontes oficiais decidem o estado de cada serviço; o IntegraNotas preenche as UFs e documentos que elas não publicam. MDF-e e DC-e são centralizados no SVRS, então derivam do estado desse autorizador. Uma fonte que falha não derruba as demais, e há um piso de cobertura (75%) abaixo do qual a coleta é considerada degradada e não é publicada — evitando exibir "tudo no ar" por engano.

Cada coleta mede a cobertura por fonte e marca quando uma fonte oficial fica degradada (cobertura abaixo do piso) — o sinal que distingue "a fonte parou de responder / mudou o HTML" de "o serviço da SEFAZ caiu".

A consulta SOAP direta aos webservices (modo soap) fornece dados mais ricos, mas exige saída de rede e, em vários autorizadores, um certificado A1 (mTLS). É opcional e desativada por padrão.

Notificações

Opcionalmente, o monitor alerta quando o estado muda. Cada canal só é ativado quando suas variáveis de ambiente existem; sem nenhuma configuração, a notificação fica desligada e o pipeline segue idêntico.

Eventos:

Evento Quando dispara
SERVICE_DOWN / SERVICE_RECOVERED Um serviço saiu / voltou ao ar.
CONTINGENCY_ENTERED / CONTINGENCY_EXITED Entrou / saiu de contingência (SVC).
TECHNICAL_NOTE Nova Nota Técnica publicada no portal.
SOURCE_DEGRADED Uma fonte oficial ficou degradada (drift).
DAILY_DIGEST Resumo diário de saúde (opcional, por hora configurável).

Canais: Discord, Slack, Telegram e webhook genérico (recebe o evento como JSON cru). As variáveis (NOTIFY_DISCORD_WEBHOOK_URL, NOTIFY_SLACK_WEBHOOK_URL, NOTIFY_TELEGRAM_BOT_TOKEN + NOTIFY_TELEGRAM_CHAT_ID, NOTIFY_WEBHOOK_URL, NOTIFY_EVENTS, NOTIFY_DIGEST_HOUR) estão documentadas em .env.example. Funciona tanto no caminho estático (via GitHub Actions) quanto no self-host (API).

Dashboard

  • Uma página por estado (/sefaz-sp/, /sefaz-mg/…) com o status ao vivo da UF, quem autoriza cada documento, a contingência da NF-e e links para as demais.
  • Mapa do Brasil clicável, cada UF colorida pelo pior estado agregado.
  • Cards por serviço com badge de estado, tempo de resposta e sparkline de latência.
  • Histórico de uptime (24h/72h) com barra estilo status-page e gráfico de latência.
  • Filtros por documento e por UF; banner de saúde geral.
  • Três modos de layout (Operação, Painel, Painel + métricas) e tema claro/escuro.
  • Últimas Notas Técnicas e um FAQ explicando cStat, autorizadores e contingência.

API HTTP

No modo self-host, a API expõe (base /api/v1):

Método Rota Retorna
GET /health { status: 'ok' }
GET /status Snapshot atual; filtros ?document=&uf=&env=
GET /status/:document/:uf Status de um serviço específico
GET /summary Agregado: disponibilidade, no ar, com problema, latência média, por documento e por autorizador
GET /services/:id/history Série histórica (?period=24h|72h)
GET /services/:id/uptime Uptime %, total de checagens, latência média
GET /incidents Incidentes derivados da série
GET /stream SSE — deltas de mudança de estado em tempo real

O Cloudflare Worker expõe um subconjunto ao vivo (/summary, /health, o snapshot completo e o histórico acumulado em /history e /services/:id/history). Também aceita /collect, que grava uma amostra sob demanda — o mesmo caminho do Cron Trigger, recusando chamadas mais frequentes que a própria cadência de coleta.

Cadência da coleta

O status exibido é sempre ao vivo — cada carregamento consulta as fontes na hora. O que precisa ser acumulado é o histórico, e ele vem de duas origens com resoluções bem diferentes:

Origem Cadência Retenção Papel
Cloudflare Worker (Cron Trigger + KV) 5 min — 288 pontos/dia 72h Fonte primária do histórico
GitHub Actions (JSONs versionados) ~4h na prática 7 dias Rede de segurança, e o modo sem infra

O cron do GitHub Actions é declarado de hora em hora, mas é best-effort: na série real medimos gap mediano de ~4h (p90 de 5h28). Com ~6 coletas por dia, uma barra de uptime de 24h era desenhada com 7 amostras e uma queda de poucas horas podia passar inteira entre duas coletas. O Cron Trigger do Worker resolve isso — a resolução passa a ser a do incidente, não a do agendador.

O histórico do Worker é guardado num formato compacto (packages/contracts): o estado vira run-length (segmento novo só quando muda) e a latência é agregada por hora. Isso mantém 72h × 135 serviços em ~230 KB numa única chave de KV — 288 escritas/dia, dentro do free tier — em vez dos megabytes que um ponto por checagem exigiria. A SPA expande de volta para pontos, na resolução que cada componente precisa.

Uso

A forma mais simples é acessar o site publicado.

Para rodar localmente é necessário Node 22.12+ e pnpm.

pnpm install

# Gera os arquivos de status consultando as fontes públicas
pnpm --filter @monitor-sefaz/collector collect ./apps/web/public/data

# Sobe o dashboard em http://localhost:5173
pnpm --filter @monitor-sefaz/web dev

Deploy

O mesmo motor de coleta alimenta três formas de rodar:

SPA estática (GitHub Pages). Um GitHub Actions coleta e versiona os JSONs; a SPA apenas os lê. Não requer infraestrutura. O build pré-renderiza a home e as 27 páginas por UF: o conteúdo chega no HTML, pronto para buscadores, e o status ao vivo vem depois, por fetch.

Cloudflare Worker. O Worker faz a coleta ao vivo com CORS, e um Cron Trigger acumula o histórico de 5 em 5 minutos no Workers KV.

# Deploy (requer wrangler login)
pnpm --filter @monitor-sefaz/worker deploy

O id do namespace de KV em apps/worker/wrangler.toml aponta para a conta do deploy oficial. Num fork, crie o seu e substitua:

pnpm --filter @monitor-sefaz/worker exec wrangler kv namespace create HISTORY

Sem o binding HISTORY o Worker continua funcionando, apenas sem acumular histórico: /history responde 501 e a SPA cai no JSON estático.

Self-host. API Fastify com Redis, scheduler e SSE, servindo o dashboard. É o único modo com histórico persistido, tempo real e suporte ao modo SOAP+A1.

docker compose up --build   # http://localhost:3333

Configuração

O front escolhe a fonte de dados por variável de ambiente: com VITE_API_BASE_URL definida consome a API/Worker ao vivo; vazia, lê os JSONs estáticos.

O build do site pré-renderiza a home e as páginas por UF, e lê mais três variáveis:

  • SITE_URL: URL pública absoluta, usada no canonical, no Open Graph e no sitemap. O padrão é o deploy oficial.
  • GOOGLE_SITE_VERIFICATION / BING_SITE_VERIFICATION: códigos de verificação do Google Search Console e do Bing Webmaster Tools. Viram as meta tags google-site-verification e msvalidate.01 em todas as páginas. Aceitam o código puro ou a <meta> inteira, como o painel a mostra. No Google, o nome do arquivo do método "Arquivo HTML" (google….html) também serve: o build grava o arquivo na raiz do site. No deploy oficial, vêm de um secret, de uma variável do repositório ou da environment github-pages.

A API self-host lê as variáveis de um .env na raiz (veja .env.example):

  • STATUS_SOURCE — hybrid (consenso multi-fonte, padrão), availability (só a página oficial) ou soap (consulta SOAP direta)
  • REDIS_URL — conexão com o Redis
  • SEFAZ_CERT_PATH / SEFAZ_CERT_PASSPHRASE — certificado A1 (.pfx) para o modo soap
  • CRON_EXPRESSION, SEFAZ_TIMEOUT_MS, SEFAZ_CONCURRENCY, HISTORY_RETENTION_MS, RATE_LIMIT_MAX
  • NOTIFY_* — canais de notificação (ver seção acima)

Homologação não aparece: a página pública da SEFAZ cobre apenas produção, e o ambiente de homologação só é alcançável pelo modo soap.

Arquitetura

Monorepo TypeScript (strict) gerenciado com pnpm e Turborepo.

packages/catalog     UFs, cStat, endpoints e o mapa UF -> autorizador
packages/core        motor de coleta: consenso multi-fonte, SOAP e notas técnicas
packages/contracts   schemas Zod e DTOs compartilhados
packages/notifier    detecção de transições e canais de notificação
apps/collector       CLI que gera os JSONs versionados (GitHub Actions)
apps/worker          Cloudflare Worker de coleta ao vivo
apps/api             API Fastify self-host: scheduler, REST, SSE e Redis
apps/web             dashboard React + Vite

Os três caminhos (collector, worker e API) usam o mesmo motor de consenso e o mesmo piso de cobertura, para os números baterem entre as pontas.

Pacotes no npm

Os quatro pacotes de packages/ são publicados sob o escopo @monitor-sefaz e podem ser usados fora do projeto:

Pacote Serve para
@monitor-sefaz/catalog Mapa UF → autorizador, endpoints dos webservices e tabela de cStat. Sem dependências.
@monitor-sefaz/core Motor de coleta: consenso multi-fonte, parsers dos portais e consulta SOAP.
@monitor-sefaz/contracts Schemas Zod e DTOs — úteis para validar as respostas da API pública.
@monitor-sefaz/notifier Detecção de transições e canais de notificação.
npm i @monitor-sefaz/catalog

O versionamento usa changesets; a publicação é feita pelo workflow release.yml, com provenance via OIDC. Os apps não são publicados.

Comandos, a partir da raiz:

pnpm build        builda todos os pacotes e apps
pnpm dev          sobe os apps em modo desenvolvimento
pnpm test         roda os testes (Vitest)
pnpm typecheck    checagem de tipos
pnpm lint         ESLint

São 308 testes (Vitest), com as respostas da SEFAZ mockadas por fixtures em packages/core/test — os testes nunca dependem da rede. O CI roda lint, typecheck e testes em cada pull request; um workflow separado e não-bloqueante faz uma coleta ao vivo periódica e alerta se uma fonte oficial degradar, capturando o drift do portal que as fixtures estáticas não pegam.

Referências

Portais oficiais de disponibilidade e fontes que o monitor consome:

Contribuindo

Contribuições são bem-vindas. O fluxo de desenvolvimento, os padrões de código e o passo a passo para adicionar um documento ou autorizador estão em CONTRIBUTING.md. Para relatar uma falha de segurança, veja SECURITY.md.

Licença

MIT © Felipe Sauer

About

A SEFAZ está fora do ar? Monitor open-source de disponibilidade dos webservices de NF-e, NFC-e, CT-e, MDF-e e DC-e nas 27 UFs — status ao vivo, histórico de uptime e alertas, sem certificado digital.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

12 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages