Claude-skill-registry Fiscalzen SEFAZ

Integrações SEFAZ (NF-e/CT-e/MDF-e) no padrão FiscalZen: DistDFe, Manifestação e eventos — com certificados A1, SOAP, retry/backoff e persistência no produto.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/fiscalzen-sefaz" ~/.claude/skills/majiayu000-claude-skill-registry-fiscalzen-sefaz && rm -rf "$T"
manifest: skills/data/fiscalzen-sefaz/SKILL.md
source content

🏗️ Contexto do Projeto (como o FiscalZen é estruturado)

  • Monorepo com pnpm-workspace + Turborepo
  • Código em TypeScript (ESM
    "type": "module"
    )
  • Backend: Fastify 4 (apps/api)
  • Jobs: BullMQ (workers + scheduler)
  • Persistência: Drizzle ORM + PostgreSQL
  • Cache/queues: Redis
  • Logging: Pino
  • Pacote fiscal principal:
    @fiscalzen/sefaz-client
    (NF-e/CT-e/MDF-e)
  • Parser fiscal:
    @fiscalzen/xml-parser
    (usado pelo sefaz-client e api)

✅ Regra: alterações de SEFAZ geralmente tocam packages/ (cliente) e/ou apps/api/ (orquestração + persistência).


🎯 Objetivo (o que esta skill resolve)

Aplicar mudanças relacionadas a SEFAZ mantendo consistência com a codebase:

  • Preferir abstrações internas (
    @fiscalzen/sefaz-client
    ) em vez de reimplementar SOAP/assinatura/certificado
  • Validar certificado e permissões no backend antes de chamar SEFAZ
  • Respeitar retry/backoff e throttling
  • Persistir eventos e atualizar documentos do jeito do produto
  • Garantir validação (unit/integration + homolog)

🧭 Onde mexer (mapa rápido)

Cliente SEFAZ (packages/sefaz-client)

  • packages/sefaz-client/src/client.ts
    → política de timeout/retry/backoff,
    https.Agent
    ,
    dispose()
    , logging
  • packages/sefaz-client/src/soap-client.ts
    +
    src/soap/envelope.ts
    → SOAP + envelope
  • packages/sefaz-client/src/services/*
    → implementações por domínio:
    • nfe-distdfe.ts
      (DistDFe NF-e)
    • cte-distdfe.ts
      ,
      mdfe-distdfe.ts
      (DistDFe CT-e/MDF-e)
    • manifestacao.ts
      (eventos do destinatário)
    • event-query.ts
      (consulta eventos)
    • cte-events.ts
      (eventos CT-e)
  • packages/sefaz-client/src/types.ts
    → contratos + erros tipados (
    SefazError
    ,
    TimeoutError
    ,
    CertificadoError
    , etc.)
  • packages/sefaz-client/src/certificate.ts
    → A1 (PFX), cache/invalidação, validações
  • packages/sefaz-client/src/signature.ts
    → digest/assinatura (helpers)

Produto (apps/api)

  • apps/api/src/modules/manifestacao/service.ts
    → fluxo real de manifestação + persistência
  • apps/api/src/modules/certificates/*
    → validação de certificados (gate antes de SEFAZ)
  • apps/api/src/modules/documents/*
    → documento + status/manifestações
  • apps/api/src/jobs/queues.ts
    → criação/agenda de jobs SEFAZ
  • apps/api/src/modules/nsu/*
    +
    packages/database/src/schema/nsu-control.ts
    → controle de NSU/sync

✅ Regras obrigatórias (gates)

1) Sempre validar certificado antes de chamar SEFAZ (no produto)

Se a chamada vier do

apps/api
, não chame SEFAZ sem passar pelo gate:

  • empresa existe
  • company.certificate
    e
    company.certificatePassword
    existem
  • certificado não expirou
  • (se aplicável) tenantId correto (multi-tenant)

2) Não vazar segredo (PFX/senha)

  • nunca logar senha do certificado
  • nunca logar buffer do PFX
  • ao logar erro, sanitize campos sensíveis

3) TLS estrito

  • não desabilitar validação TLS (
    rejectUnauthorized
    )

4) Erros externos padronizados

No

apps/api
, problemas da SEFAZ devem virar erro de serviço externo (padrão do projeto), mantendo mensagem útil.


🔁 Retry/Backoff e Throttling (padrão FiscalZen)

Ponto único de política:
packages/sefaz-client/src/client.ts

✅ Regra: se você precisar mudar retry/backoff/timeout, faça no client (não espalhe retry pelos services).

Throttling (ex.: cStat 656)

Recomendação de implementação consistente:

  • tratar como erro recuperável
  • aplicar retry com backoff exponencial + jitter
  • evitar tempestade: preferir job/queue para processar em série por empresa/UF

📦 DistDFe (Golden Path) — como fazer no FiscalZen

Cenários típicos

  • Consulta por último NSU (sync contínuo)
  • Consulta por NSU específico
  • Consulta por chave (pontual)

Padrão de implementação

  1. Validar parâmetros (CNPJ, chave, nsu/ultNSU)
  2. Montar request XML conforme tipo de consulta
  3. Enviar via
    SoapClient
    /
    SefazClient
    (abstração interna)
  4. Parsear retorno (cStat/xMotivo/ultNSU/maxNSU)
  5. Extrair
    docZip
    e:
    • decodificar
    • detectar schema
    • derivar tipo/chave usando
      @fiscalzen/xml-parser
  6. Retornar
    DistDFeResponse
    consistente
  7. Se estiver no produto (apps/api): persistir e atualizar controle de NSU

Regras de robustez

  • nsu
    e
    ultNSU
    sempre como string com 15 dígitos (
    padStart(15,'0')
    )
  • docZip inválido não deve derrubar o lote inteiro (registrar erro e seguir)
  • ao tratar throttling, preferir política central no client

🧾 Manifestação do Destinatário (Golden Path) — padrão do produto

Passo a passo (apps/api)

  1. obter empresa com certificado (gate)
  2. buscar documento por chave com tenantId
  3. montar
    CertificadoA1
    no formato do
    @fiscalzen/sefaz-client
  4. usar
    env.SEFAZ_AMBIENTE
  5. chamar o client do pacote
  6. se
    sucesso=false
    : lançar
    ExternalServiceError('SEFAZ', xMotivo)
  7. persistir em
    documentEvents
    + atualizar
    documents.manifestacao

Regras específicas

  • eventos devem ser idempotentes na camada do produto (não duplicar o mesmo evento sem necessidade)
  • manter rastreabilidade (documentId/chave/tipoEvento/protocolo/dataRegistro)

🧪 Validação (Fase V) — mínimo obrigatório

Unit / pacote (sefaz-client)

  • validar
    validateParams
    (CNPJ/chave)
  • validar montagem de request por ultNSU/nsu/chave
  • validar parsing de resposta (cStat e campos)
  • validar docZip: sucesso e falha isolada

Integration / produto (apps/api)

  • empresa sem certificado → erro de validação
  • certificado expirado → erro de validação
  • documento inexistente → NotFound
  • retorno
    sucesso=false
    da SEFAZ → ExternalServiceError
  • persistência: criou event + atualizou documento

Homologação

  • testar ao menos:
    • DistDFe por ultNSU
    • Manifestação (um evento)
    • cenário de throttling (se possível reproduzir)

🧰 Prompt templates (como invocar a skill)

Manifestação (produto)

“Aplique a skill

fiscalzen-sefaz
para ajustar o fluxo de manifestação em
apps/api
.
Preserve o gate de certificado + multi-tenant e mapeie falhas SEFAZ para erro externo padrão. Atualize persistência em
documentEvents
e
documents.manifestacao
.”

DistDFe (pacote)

“Aplique a skill

fiscalzen-sefaz
para modificar
packages/sefaz-client/src/services/nfe-distdfe.ts
.
Preserve validações, padStart(15) e parsing docZip com
@fiscalzen/xml-parser
. Se tratar 656, preferir política central no client.”