> ## Documentation Index
> Fetch the complete documentation index at: https://docs.validatech.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Armazenamento Seguro de NFe

> Mantenha suas NFe organizadas e seguras na nuvem com backup fiscal completo

## Visão Geral

O armazenamento seguro de NFe é fundamental para empresas que precisam manter conformidade fiscal e facilitar auditorias. Com a API GuardaNFe da ValidaNFe, você pode criar um sistema completo de backup fiscal na nuvem.

<Card title="Benefícios do Armazenamento Seguro">
  * **Conformidade fiscal** garantida por até 10 anos
  * **Backup automático** com redundância geográfica
  * **Busca e recuperação** rápida de documentos
  * **Auditoria facilitada** com logs completos de acesso
</Card>

## Arquitetura de Armazenamento

<Steps>
  <Step title="Recebimento">
    NFe recebidas são processadas e validadas automaticamente
  </Step>

  <Step title="Indexação">
    Metadados extraídos para busca e categorização eficiente
  </Step>

  <Step title="Armazenamento">
    XML original armazenado com criptografia AES-256
  </Step>

  <Step title="Backup">
    Replicação automática em múltiplas regiões geográficas
  </Step>

  <Step title="Acesso">
    Interface de consulta e download com controle de permissões
  </Step>
</Steps>

## Implementação Básica

### 1. Sistema de Upload Automático

```javascript theme={null}
import { ValidaNFeSDK } from 'validanfe-sdk';
import fs from 'fs';
import path from 'path';

class ArmazenadorNFe {
  constructor() {
    this.validanfe = new ValidaNFeSDK({
      apiKey: process.env.VALIDANFE_API_KEY
    });
  }

  async processarDiretorio(diretorio) {
    const arquivos = fs.readdirSync(diretorio);
    const xmlFiles = arquivos.filter(file => file.endsWith('.xml'));

    console.log(`Processando ${xmlFiles.length} arquivos XML...`);

    for (const arquivo of xmlFiles) {
      try {
        await this.processarArquivo(path.join(diretorio, arquivo));
      } catch (error) {
        console.error(`Erro ao processar ${arquivo}:`, error.message);
      }
    }
  }

  async processarArquivo(caminhoArquivo) {
    const xmlContent = fs.readFileSync(caminhoArquivo, 'utf8');
    const chaveNFe = this.extrairChaveNFe(xmlContent);

    if (!chaveNFe) {
      throw new Error('Chave NFe não encontrada no XML');
    }

    // Verificar se já existe no GuardaNFe
    const jaExiste = await this.verificarSeExiste(chaveNFe);
    if (jaExiste) {
      console.log(`NFe ${chaveNFe} já armazenada`);
      return;
    }

    // Armazenar no GuardaNFe
    const resultado = await this.validanfe.guarda.armazenar({
      chave: chaveNFe,
      xml: xmlContent,
      metadata: {
        origem: 'upload_automatico',
        arquivo_original: path.basename(caminhoArquivo),
        processado_em: new Date().toISOString()
      }
    });

    console.log(`NFe ${chaveNFe} armazenada com sucesso. ID: ${resultado.arquivoId}`);

    // Salvar referência no banco local
    await this.salvarReferencia({
      chave_nfe: chaveNFe,
      arquivo_id: resultado.arquivoId,
      url_download: resultado.urlDownload,
      arquivo_original: path.basename(caminhoArquivo),
      armazenado_em: new Date()
    });
  }

  extrairChaveNFe(xmlContent) {
    const match = xmlContent.match(/<infNFe[^>]*Id="NFe(\d{44})"/);
    return match ? match[1] : null;
  }

  async verificarSeExiste(chaveNFe) {
    try {
      await this.validanfe.guarda.verificar({ chave: chaveNFe });
      return true;
    } catch (error) {
      if (error.status === 404) {
        return false;
      }
      throw error;
    }
  }
}
```

### 2. Sistema de Backup Incremental

```javascript theme={null}
class BackupIncremental {
  constructor() {
    this.armazenador = new ArmazenadorNFe();
    this.ultimaVerificacao = this.carregarUltimaVerificacao();
  }

  async executarBackup() {
    console.log('Iniciando backup incremental...');

    // Buscar NFe modificadas desde última verificação
    const nfesModificadas = await this.buscarNFesModificadas();
    
    for (const nfe of nfesModificadas) {
      try {
        await this.processarNFe(nfe);
      } catch (error) {
        console.error(`Erro ao processar NFe ${nfe.chave}:`, error.message);
        await this.registrarErro(nfe.chave, error.message);
      }
    }

    // Atualizar timestamp da última verificação
    this.ultimaVerificacao = new Date();
    await this.salvarUltimaVerificacao(this.ultimaVerificacao);

    console.log(`Backup incremental concluído. ${nfesModificadas.length} NFe processadas.`);
  }

  async buscarNFesModificadas() {
    return await database.nfes.find({
      $or: [
        { modificado_em: { $gte: this.ultimaVerificacao } },
        { guardanfe_id: { $exists: false } }
      ]
    });
  }

  async processarNFe(nfe) {
    if (!nfe.guardanfe_id) {
      // Primeira vez - armazenar
      const resultado = await this.armazenador.validanfe.guarda.armazenar({
        chave: nfe.chave,
        xml: nfe.xml_content,
        metadata: {
          empresa_id: nfe.empresa_id,
          tipo: nfe.tipo,
          valor: nfe.valor_total,
          data_emissao: nfe.data_emissao
        }
      });

      await database.nfes.updateOne(
        { _id: nfe._id },
        { 
          guardanfe_id: resultado.arquivoId,
          guardanfe_url: resultado.urlDownload,
          backup_em: new Date()
        }
      );
    } else {
      // Atualizar se necessário
      await this.verificarEAtualizar(nfe);
    }
  }

  async verificarEAtualizar(nfe) {
    try {
      const info = await this.armazenador.validanfe.guarda.obterInfo({
        arquivoId: nfe.guardanfe_id
      });

      // Verificar se precisa atualizar
      if (info.hash !== this.calcularHashXML(nfe.xml_content)) {
        await this.armazenador.validanfe.guarda.atualizar({
          arquivoId: nfe.guardanfe_id,
          xml: nfe.xml_content
        });
        
        console.log(`NFe ${nfe.chave} atualizada no GuardaNFe`);
      }
    } catch (error) {
      console.error(`Erro ao verificar NFe ${nfe.chave}:`, error.message);
    }
  }
}
```

### 3. Sistema de Busca e Recuperação

```javascript theme={null}
class BuscadorNFe {
  constructor() {
    this.validanfe = new ValidaNFeSDK({
      apiKey: process.env.VALIDANFE_API_KEY
    });
  }

  async buscar(filtros) {
    const { 
      dataInicio, 
      dataFim, 
      cnpjEmitente, 
      valorMinimo, 
      valorMaximo,
      status,
      limite = 50,
      pagina = 1
    } = filtros;

    // Buscar no banco local primeiro (mais rápido)
    const query = this.construirQuery(filtros);
    const nfesLocais = await database.nfes
      .find(query)
      .limit(limite)
      .skip((pagina - 1) * limite)
      .sort({ data_emissao: -1 });

    // Enriquecer com URLs de download do GuardaNFe
    const nfesEnriquecidas = await Promise.all(
      nfesLocais.map(async (nfe) => {
        if (nfe.guardanfe_id) {
          try {
            const urlDownload = await this.obterUrlDownload(nfe.guardanfe_id);
            return { ...nfe.toObject(), url_download: urlDownload };
          } catch (error) {
            console.error(`Erro ao obter URL para NFe ${nfe.chave}:`, error.message);
            return nfe.toObject();
          }
        }
        return nfe.toObject();
      })
    );

    return {
      nfes: nfesEnriquecidas,
      total: await database.nfes.countDocuments(query),
      pagina,
      limite
    };
  }

  construirQuery(filtros) {
    const query = {};

    if (filtros.dataInicio || filtros.dataFim) {
      query.data_emissao = {};
      if (filtros.dataInicio) {
        query.data_emissao.$gte = new Date(filtros.dataInicio);
      }
      if (filtros.dataFim) {
        query.data_emissao.$lte = new Date(filtros.dataFim);
      }
    }

    if (filtros.cnpjEmitente) {
      query.cnpj_emitente = filtros.cnpjEmitente;
    }

    if (filtros.valorMinimo || filtros.valorMaximo) {
      query.valor_total = {};
      if (filtros.valorMinimo) {
        query.valor_total.$gte = parseFloat(filtros.valorMinimo);
      }
      if (filtros.valorMaximo) {
        query.valor_total.$lte = parseFloat(filtros.valorMaximo);
      }
    }

    if (filtros.status) {
      query.status = filtros.status;
    }

    return query;
  }

  async obterUrlDownload(arquivoId) {
    const info = await this.validanfe.guarda.obterInfo({ arquivoId });
    return info.urlDownload;
  }

  async baixarNFe(chaveNFe) {
    const nfe = await database.nfes.findOne({ chave: chaveNFe });
    
    if (!nfe || !nfe.guardanfe_id) {
      throw new Error('NFe não encontrada no armazenamento');
    }

    const xmlContent = await this.validanfe.guarda.baixar({
      arquivoId: nfe.guardanfe_id
    });

    // Registrar acesso para auditoria
    await this.registrarAcesso({
      chave_nfe: chaveNFe,
      usuario: 'sistema', // ou ID do usuário
      tipo_acesso: 'download',
      timestamp: new Date()
    });

    return {
      chave: chaveNFe,
      xml: xmlContent,
      metadata: nfe.toObject()
    };
  }
}
```

## Casos de Uso Avançados

### Organização por Categorias

<Tabs>
  <Tab title="Por Período Fiscal">
    ```javascript theme={null}
    class OrganizadorPeriodoFiscal {
      async organizarPorAno(ano) {
        const nfes = await database.nfes.find({
          data_emissao: {
            $gte: new Date(`${ano}-01-01`),
            $lt: new Date(`${ano + 1}-01-01`)
          }
        });

        const organizacao = {
          ano: ano,
          trimestres: {},
          totais: {
            quantidade: nfes.length,
            valor_total: 0
          }
        };

        nfes.forEach(nfe => {
          const trimestre = Math.ceil((nfe.data_emissao.getMonth() + 1) / 3);
          
          if (!organizacao.trimestres[trimestre]) {
            organizacao.trimestres[trimestre] = {
              nfes: [],
              valor_total: 0
            };
          }

          organizacao.trimestres[trimestre].nfes.push({
            chave: nfe.chave,
            valor: nfe.valor_total,
            emitente: nfe.nome_emitente,
            data: nfe.data_emissao
          });

          organizacao.trimestres[trimestre].valor_total += nfe.valor_total;
          organizacao.totais.valor_total += nfe.valor_total;
        });

        return organizacao;
      }
    }
    ```
  </Tab>

  <Tab title="Por Fornecedor">
    ```javascript theme={null}
    class OrganizadorFornecedor {
      async agruparPorFornecedor(filtros = {}) {
        const pipeline = [
          { $match: this.construirFiltros(filtros) },
          {
            $group: {
              _id: '$cnpj_emitente',
              nome_emitente: { $first: '$nome_emitente' },
              quantidade_nfes: { $sum: 1 },
              valor_total: { $sum: '$valor_total' },
              primeira_nfe: { $min: '$data_emissao' },
              ultima_nfe: { $max: '$data_emissao' },
              nfes: {
                $push: {
                  chave: '$chave',
                  valor: '$valor_total',
                  data: '$data_emissao',
                  guardanfe_id: '$guardanfe_id'
                }
              }
            }
          },
          { $sort: { valor_total: -1 } }
        ];

        const resultado = await database.nfes.aggregate(pipeline);
        
        return resultado.map(fornecedor => ({
          cnpj: fornecedor._id,
          nome: fornecedor.nome_emitente,
          estatisticas: {
            quantidade_nfes: fornecedor.quantidade_nfes,
            valor_total: fornecedor.valor_total,
            periodo: {
              inicio: fornecedor.primeira_nfe,
              fim: fornecedor.ultima_nfe
            }
          },
          nfes: fornecedor.nfes
        }));
      }
    }
    ```
  </Tab>
</Tabs>

### Auditoria e Compliance

```javascript theme={null}
class AuditoriaArmazenamento {
  async gerarRelatorioAuditoria(periodo) {
    const relatorio = {
      periodo: periodo,
      estatisticas: await this.calcularEstatisticas(periodo),
      integridade: await this.verificarIntegridade(periodo),
      acessos: await this.relatarAcessos(periodo),
      conformidade: await this.verificarConformidade(periodo)
    };

    return relatorio;
  }

  async verificarIntegridade(periodo) {
    const nfes = await this.buscarNFesPeriodo(periodo);
    const verificacoes = [];

    for (const nfe of nfes) {
      if (nfe.guardanfe_id) {
        try {
          const info = await this.validanfe.guarda.obterInfo({
            arquivoId: nfe.guardanfe_id
          });

          const integridadeOk = info.hash === this.calcularHashXML(nfe.xml_content);
          
          verificacoes.push({
            chave_nfe: nfe.chave,
            integridade: integridadeOk ? 'OK' : 'FALHA',
            ultima_verificacao: new Date(),
            tamanho_arquivo: info.tamanho,
            hash_esperado: this.calcularHashXML(nfe.xml_content),
            hash_armazenado: info.hash
          });

        } catch (error) {
          verificacoes.push({
            chave_nfe: nfe.chave,
            integridade: 'ERRO',
            erro: error.message
          });
        }
      }
    }

    return {
      total_verificado: verificacoes.length,
      integras: verificacoes.filter(v => v.integridade === 'OK').length,
      com_falha: verificacoes.filter(v => v.integridade === 'FALHA').length,
      com_erro: verificacoes.filter(v => v.integridade === 'ERRO').length,
      detalhes: verificacoes
    };
  }

  async verificarConformidade(periodo) {
    const nfes = await this.buscarNFesPeriodo(periodo);
    
    const conformidade = {
      prazo_armazenamento: this.verificarPrazoArmazenamento(nfes),
      backup_geografico: await this.verificarBackupGeografico(nfes),
      criptografia: await this.verificarCriptografia(nfes),
      acesso_controlado: await this.verificarControleAcesso(periodo)
    };

    return conformidade;
  }
}
```

### API REST para Acesso

```javascript theme={null}
// Endpoints para acesso ao armazenamento
app.get('/api/nfes/buscar', async (req, res) => {
  try {
    const buscador = new BuscadorNFe();
    const resultado = await buscador.buscar(req.query);
    res.json(resultado);
  } catch (error) {
    res.status(500).json({ erro: error.message });
  }
});

app.get('/api/nfes/:chave/download', async (req, res) => {
  try {
    const buscador = new BuscadorNFe();
    const nfe = await buscador.baixarNFe(req.params.chave);
    
    res.setHeader('Content-Type', 'application/xml');
    res.setHeader('Content-Disposition', `attachment; filename="${nfe.chave}.xml"`);
    res.send(nfe.xml);
  } catch (error) {
    res.status(404).json({ erro: error.message });
  }
});

app.get('/api/auditoria/:ano', async (req, res) => {
  try {
    const auditor = new AuditoriaArmazenamento();
    const relatorio = await auditor.gerarRelatorioAuditoria({
      inicio: new Date(`${req.params.ano}-01-01`),
      fim: new Date(`${req.params.ano}-12-31`)
    });
    
    res.json(relatorio);
  } catch (error) {
    res.status(500).json({ erro: error.message });
  }
});
```

## Benefícios do Armazenamento Seguro

<CardGroup cols={2}>
  <Card title="Conformidade Legal">
    **10 anos de retenção** conforme legislação fiscal brasileira

    * Backup automático com redundância
    * Logs de auditoria completos
  </Card>

  <Card title="Segurança Avançada">
    **Criptografia AES-256** e controle de acesso granular

    * Múltiplas réplicas geográficas
    * Verificação de integridade automática
  </Card>

  <Card title="Performance">
    **Busca instantânea** em milhões de documentos

    * Indexação inteligente por metadados
    * Cache distribuído para downloads
  </Card>

  <Card title="Economia">
    **70% de redução** nos custos de armazenamento físico

    * Eliminação de servidores físicos
    * Redução de equipe de TI dedicada
  </Card>
</CardGroup>

## Próximos Passos

<Steps>
  <Step title="Avaliar Volume">
    Determine a quantidade de NFe que precisa armazenar
  </Step>

  <Step title="Configurar API">
    Configure sua conta ValidaNFe e credentials da API GuardaNFe
  </Step>

  <Step title="Implementar Upload">
    Desenvolva o sistema de upload automático das NFe
  </Step>

  <Step title="Configurar Backup">
    Implemente rotinas de backup incremental
  </Step>

  <Step title="Testar Recuperação">
    Teste os procedimentos de busca e recuperação
  </Step>

  <Step title="Monitorar Compliance">
    Configure auditorias automáticas de conformidade
  </Step>
</Steps>

<Card title="Consultoria em Armazenamento Fiscal" href="mailto:consultoria@validanfe.com">
  Precisa de ajuda para planejar sua estratégia de armazenamento? Nossa equipe especializada pode ajudar.
</Card>
