Skip to content

Logs e Auditoria

CAKeysama edited this page Sep 30, 2026 · 1 revision

Logs e Auditoria

Toda ação relevante gera um registro imutável na coleção audit_logs. Só a Administração consulta, pela tela Administração → Histórico de ações (/administracao/logs).

Campos de um registro

Campo Conteúdo
usuarioUid, usuarioNome, usuarioEmail, usuarioPerfil Quem executou (o usuarioUid é sempre o da sessão; as regras garantem)
acao Tipo da ação: um token estável, como aprovacao_usuario
categoria Agrupamento: autenticacao, usuarios, dados ou fluxo
acaoDescricao Ação realizada em texto, como "Aprovou o cadastro de Ana com o cargo Projetista"
resultado sucesso, falha ou negado
tipoEntidade, entidadeId, entidadeNome Recurso afetado e seu identificador
conteudo, dadosAnteriores, detalhes Informações adicionais em JSON: valores novos e anteriores, motivos, totais
dataHora Data e hora ISO, usada na ordenação
dataHoraServidor Carimbo do servidor (serverTimestamp), exibido na tela; as regras exigem que seja o horário real da gravação

O que é registrado

Categoria Ações (acao) Origem
Autenticação login (inclusive acesso recusado), logout, cadastro, troca_senha AuthContext, casos de uso
Usuários e cargos aprovacao_usuario, rejeicao_usuario, criacao_usuario, redefinicao_senha, alteracao_perfil, bloqueio_usuario, desbloqueio_usuario, solicitacao_cargo, aprovacao_cargo, rejeicao_cargo AuthContext, casos de uso, Cloud Function
Alteração de dados criacao, edicao, exclusao, importacao ReToolContext (dispositivos, classificações, reutilizações, importação e propagação de imagens) e AuthContext (exclusão de usuário)
Fluxo de reutilização transicao, aprovacao, rejeicao ReToolContext (transicionarReutilizacao)

Tipos de recurso (tipoEntidade): dispositivo, categoria, tipo, familia, produto, reutilizacao, usuario, solicitacao_cargo, sessao.

O resultado indica:

  • negado:
    • tentativa de aprovar ou rejeitar cadastros, criar contas, decidir solicitações de cargo ou gerar nova senha sem ser Administração;
    • login de conta bloqueada ou rejeitada.
  • falha: erro nessas operações e na troca de senha (senha temporária incorreta).
  • sucesso: os demais casos. Registros antigos sem o campo contam como sucesso.

Falhas ao gravar um log não interrompem a operação principal: o erro vai para o console.

Dados que nunca são registrados

Antes de gravar, sanitizarDadosAuditoria() (em src/domain/entities/auditLog.ts) remove, em qualquer nível do objeto, os campos cujo nome indica segredo:

  • por palavra: senha, password, passwd, pwd, token, secret, segredo, hash, credential, credencial;
  • por termo composto: apiKey, privateKey, userPassword e similares.

Valores booleanos, como trocaSenhaObrigatoria, são mantidos. As regras também recusam campos de senha, token e hash no primeiro nível do registro.

Nunca inclua em logs senhas (inclusive as temporárias), tokens, hashes ou credenciais.

Quem acessa

Operação Quem pode
Ler Somente Administração operacional (regras + rota + interface)
Criar Qualquer usuário autenticado, apenas em nome próprio
Alterar ou excluir Ninguém, nem a Administração (regras)

Tela Histórico de Ações

Componente HistoricoAcoesPanel, com o estado em useHistoricoAuditoriaController.

Recurso Funcionamento
Categoria Filtra pelo campo categoria gravado no registro
Ação Lista as ações da categoria escolhida; uma ação específica substitui o filtro de categoria
Usuário Autor do registro (usuarioUid)
Recurso tipoEntidade
Resultado Todos, ou só falha e negado
De / Até Período por dia, no fuso do navegador (início e fim do dia)
Buscar nesta página Texto em usuário, e-mail, recurso, ID e descrição, só nos registros da página exibida
Total Contagem feita no servidor com os mesmos filtros
Paginação 25, 50 ou 100 por página; Anterior e Próxima por cursor no servidor
Detalhes Clicar na linha mostra detalhes, conteudo, dadosAnteriores e o ID do registro
Novos registros Aviso em tempo real com o link Atualizar lista
Limpar filtros Volta à primeira página sem filtros

Mensagens de erro da tela:

Mensagem Significado
Índices não publicados Mostra o projeto consultado e o comando de deploy
Índices em construção Aguarde alguns minutos e tente de novo
Acesso negado Somente a Administração consulta o histórico

Registros anteriores ao campo categoria não aparecem no filtro de categoria, mas aparecem sem filtros e pelo filtro de ação.

Como a consulta é montada

FirestoreAuditLogRepository.listarPagina() monta a consulta nesta ordem:

  1. Filtros de igualdade, na ordem canônica CAMPOS_FILTRO_AUDITORIA: categoria ou acao, depois usuarioUid, tipoEntidade e resultado.
  2. Período: dataHora >= de e dataHora <= ate.
  3. orderBy('dataHora', 'desc'), cursor (startAfter) e limit(tamanho + 1). O item extra indica se há próxima página.

A categoria é filtrada pelo campo gravado, e não por acao in [...]. O Firestore expande cada in em sub-consultas e multiplica as expansões (10 ações × 2 resultados = 20), o que ultrapassava o limite de filtros por consulta. Hoje o único in é o de resultado, e cada consulta tem no máximo 2 sub-consultas.

Índices do Firestore

Esta é a página principal sobre os índices do projeto: eles existem apenas para esta tela. Estão em retool/firestore.indexes.json, com 23 índices compostos em audit_logs, todos no formato campos de igualdade (ascendente) + dataHora (descendente). Há um para cada combinação não vazia de:

  • categoria ou acao (nunca os dois juntos);
  • usuarioUid;
  • tipoEntidade;
  • resultado.

O Firestore só reaproveita índices em consultas apenas de igualdade. Com a ordenação e o filtro de período, cada combinação precisa do seu índice. Sem filtros, basta o índice automático de campo único de dataHora.

A lista é gerada por indicesNecessariosAuditoria(). O teste FirestoreAuditLogRepository.indices.test.ts falha se o arquivo divergir do código ou se alguma combinação da tela ficar sem índice.

Depois de mudar os índices, publique no projeto que o app usa (ver Build e Deploy):

npx firebase-tools deploy --only firestore:indexes --project fallback

Os índices levam alguns minutos para ficar prontos. O andamento aparece no Firebase Console → Firestore → Índices.

Adicionar um novo evento ou filtro

Veja Guia do Desenvolvedor → Auditoria.

Limitações

  • Senha errada no login não gera log: sem autenticação não há identidade para registrar, e as regras exigem autoria.
  • Os logs são gravados pelo cliente: as regras impedem registrar em nome de outra pessoa e antedatar, mas não validam usuarioPerfil nem o conteúdo descritivo.
  • Os registros só podem ser apagados por quem administra o projeto no Firebase (Console ou CLI), fora das regras do app.

Clone this wiki locally