Logs e Auditoria - CAKeysama/ReTool GitHub Wiki
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,userPassworde 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:
- Filtros de igualdade, na ordem canônica
CAMPOS_FILTRO_AUDITORIA:categoriaouacao, depoisusuarioUid,tipoEntidadeeresultado. - Período:
dataHora >= deedataHora <= ate. orderBy('dataHora', 'desc'), cursor (startAfter) elimit(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:
categoriaouacao(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
usuarioPerfilnem 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.