Skip to content

Auditoria

Este guia detalha o sistema de auditoria completo do ArqSystem para rastreamento de todas as operações.

Visão Geral

O ArqSystem mantém registro completo de auditoria para:

  • Criação de documentos
  • Atualização de documentos (com mudanças campo a campo)
  • Exclusão de documentos (soft delete)
  • Criação/edição/exclusão de campos
  • Upload de arquivos
  • Operações de configuração

Arquitetura

Tabela AuditLog

Modelo central de auditoria:

prisma
model AuditLog {
  id          String            @id @default(uuid())
  entityType  AuditEntityType   // DOCUMENT | UPLOADED_FILE | FIELD_CONFIGURATION
  entityId    String
  action      AuditAction       // CREATE | UPDATE | SOFT_DELETE | etc.
  userId      String
  changes     Json?
  documentId  Int?
  createdAt   DateTime          @default(now())

  user        User
  document    Document?
}

Tipos de Entidade

AuditEntityType:

  • DOCUMENT: Operações com documentos
  • UPLOADED_FILE: Operações com arquivos
  • FIELD_CONFIGURATION: Operações com configuração de campos

Tipos de Ação

AuditAction:

  • CREATE: Criação de entidade
  • UPDATE: Atualização de entidade
  • SOFT_DELETE: Exclusão lógica
  • FIELD_CREATED: Campo criado
  • FIELD_UPDATED: Campo atualizado
  • FIELD_DELETED: Campo excluído

Auditoria de Documentos

Criação de Documento

Quando um documento é criado:

typescript
await createAuditLog(tx, {
  entityType: "DOCUMENT",
  entityId: document.id.toString(),
  action: "CREATE",
  userId: ctx.user.id,
  documentId: document.id
});

Registro criado:

json
{
  "id": "audit-uuid",
  "entityType": "DOCUMENT",
  "entityId": "42",
  "action": "CREATE",
  "userId": "user-uuid",
  "documentId": 42,
  "changes": null,
  "createdAt": "2026-01-14T10:30:00Z"
}

Atualização de Documento

Sistema registra mudanças campo a campo:

Processo:

  1. Busca documento antes da atualização
  2. Converte para formato de formulário
  3. Compara valores antigos vs novos
  4. Registra apenas campos alterados

Exemplo de mudanças:

json
{
  "title": {
    "old": "Relatório 2023",
    "new": "Relatório Anual 2023"
  },
  "accessLevel": {
    "old": "Restrito",
    "new": "Público"
  },
  "description": {
    "old": "Relatório preliminar",
    "new": "Relatório final das atividades desenvolvidas em 2023"
  }
}

Registro completo:

json
{
  "id": "audit-uuid",
  "entityType": "DOCUMENT",
  "entityId": "42",
  "action": "UPDATE",
  "userId": "user-uuid",
  "documentId": 42,
  "changes": {
    "title": { "old": "...", "new": "..." },
    "accessLevel": { "old": "...", "new": "..." }
  },
  "createdAt": "2026-01-14T11:45:00Z"
}

Exclusão de Documento

Soft delete registrado:

typescript
await createAuditLog(tx, {
  entityType: "DOCUMENT",
  entityId: input.id.toString(),
  action: "SOFT_DELETE",
  userId: ctx.user.id,
  documentId: input.id
});

Nota: Documento permanece no banco com deletedAt preenchido.

Auditoria de Campos

Criação de Campo

Quando administrador cria novo campo:

json
{
  "entityType": "FIELD_CONFIGURATION",
  "entityId": "field-uuid",
  "action": "FIELD_CREATED",
  "userId": "admin-uuid",
  "changes": {
    "fieldKey": { "old": null, "new": "numeroProcesso" },
    "label": { "old": null, "new": "Número do Processo" },
    "fieldType": { "old": null, "new": "TEXT" }
  }
}

Atualização de Campo

Mudanças em configuração de campo:

json
{
  "entityType": "FIELD_CONFIGURATION",
  "entityId": "field-uuid",
  "action": "FIELD_UPDATED",
  "userId": "admin-uuid",
  "changes": {
    "label": {
      "old": "Número do Processo",
      "new": "Nº do Processo Administrativo"
    },
    "required": {
      "old": false,
      "new": true
    }
  }
}

Exclusão de Campo

Remoção de campo personalizado:

json
{
  "entityType": "FIELD_CONFIGURATION",
  "entityId": "field-uuid",
  "action": "FIELD_DELETED",
  "userId": "admin-uuid",
  "changes": null
}

Função calculateChanges

Utilitário que compara objetos e gera diff:

typescript
function calculateChanges(
  oldData: Record<string, unknown>,
  newData: Record<string, unknown>
): Record<string, { old: unknown; new: unknown }> {
  const changes: Record<string, { old: unknown; new: unknown }> = {};

  // Compara todos os campos do objeto novo
  for (const key in newData) {
    if (oldData[key] !== newData[key]) {
      changes[key] = {
        old: oldData[key],
        new: newData[key]
      };
    }
  }

  // Verifica campos removidos
  for (const key in oldData) {
    if (!(key in newData) && oldData[key] !== undefined) {
      changes[key] = {
        old: oldData[key],
        new: undefined
      };
    }
  }

  return changes;
}

Consulta de Logs

API Endpoint (Futuro)

typescript
// Buscar logs de um documento
GET /api/trpc/audit.getDocumentHistory
{
  "documentId": 42
}

// Resposta
[
  {
    "id": "log-3",
    "action": "UPDATE",
    "userId": "user-uuid",
    "user": { "name": "João Silva" },
    "changes": { "title": { "old": "...", "new": "..." } },
    "createdAt": "2026-01-14T11:45:00Z"
  },
  {
    "id": "log-2",
    "action": "UPDATE",
    "userId": "user-uuid",
    "user": { "name": "Maria Santos" },
    "changes": { "accessLevel": { "old": "Restrito", "new": "Público" } },
    "createdAt": "2026-01-13T09:20:00Z"
  },
  {
    "id": "log-1",
    "action": "CREATE",
    "userId": "user-uuid",
    "user": { "name": "João Silva" },
    "changes": null,
    "createdAt": "2026-01-10T14:30:00Z"
  }
]

Buscar por Usuário

typescript
GET /api/trpc/audit.getUserActivity
{
  "userId": "user-uuid",
  "startDate": "2026-01-01",
  "endDate": "2026-01-31"
}

Buscar por Período

typescript
GET /api/trpc/audit.getActivityByPeriod
{
  "startDate": "2026-01-01T00:00:00Z",
  "endDate": "2026-01-31T23:59:59Z",
  "entityType": "DOCUMENT" // Opcional
}

Interface de Visualização

Histórico de Documento

Página de visualização do documento (/documents/:id/view) pode exibir histórico:

┌─ Histórico de Alterações ─────────────────────┐
│                                                │
│ 14/01/2026 11:45 - João Silva                 │
│ Atualização                                    │
│   • Título: "Relatório 2023" → "Relatório     │
│     Anual 2023"                                │
│   • Acesso: "Restrito" → "Público"            │
│                                                │
│ 13/01/2026 09:20 - Maria Santos               │
│ Atualização                                    │
│   • Descrição: alterada                        │
│                                                │
│ 10/01/2026 14:30 - João Silva                 │
│ Criação do documento                           │
│                                                │
└────────────────────────────────────────────────┘

Timeline de Atividades

Interface administrativa para visualizar todas as atividades:

┌─ Auditoria do Sistema ────────────────────────┐
│                                                │
│ Filtros:                                       │
│ [Tipo: Todos ▼] [Ação: Todas ▼]               │
│ [Usuário: Todos ▼]                            │
│ [01/01/2026] - [31/01/2026]                   │
│                                                │
│ ────────────────────────────────────────────  │
│                                                │
│ 14/01 11:45 | João Silva                      │
│ Documento #42 - Atualização                   │
│ 2 campos alterados                             │
│                                                │
│ 14/01 10:30 | Maria Santos                    │
│ Documento #43 - Criação                       │
│                                                │
│ 13/01 16:20 | Admin                           │
│ Campo "Número Processo" - Criação             │
│                                                │
│ 13/01 09:20 | João Silva                      │
│ Documento #42 - Atualização                   │
│ 1 campo alterado                               │
│                                                │
└────────────────────────────────────────────────┘

Conformidade e Segurança

Retenção de Logs

Política atual: Logs permanentes

Recomendado (futuro):

  • Logs de documentos: Prazo de guarda conforme legislação
  • Logs de configuração: Mínimo 5 anos
  • Logs de acesso: Mínimo 1 ano

Imutabilidade

Logs são append-only:

  • Não podem ser editados
  • Não podem ser deletados (exceto via script de manutenção)
  • Garantia de integridade do histórico

Rastreabilidade

Todo log inclui:

  • Quem: userId do autor da ação
  • O que: action + changes detalhadas
  • Quando: createdAt (timestamp UTC)
  • Onde: entityType + entityId

Privacidade

LGPD/GDPR Compliance:

  • Logs de dados sensíveis podem ser anonimizados
  • Usuários podem solicitar histórico de suas ações
  • Sistema pode exportar logs para análise externa

Relatórios

Relatório de Atividades por Usuário

Quantidade de operações por usuário em período:

┌─ Atividades - Janeiro 2026 ────────────────┐
│                                             │
│ João Silva                                  │
│   • 45 documentos criados                   │
│   • 123 documentos atualizados              │
│   • 5 documentos excluídos                  │
│                                             │
│ Maria Santos                                │
│   • 23 documentos criados                   │
│   • 67 documentos atualizados               │
│   • 2 documentos excluídos                  │
│                                             │
└─────────────────────────────────────────────┘

Relatório de Documentos Mais Editados

Documentos com mais alterações:

┌─ Documentos com Mais Edições ──────────────┐
│                                             │
│ 1. Relatório Anual 2024 (#42)              │
│    15 edições - Última: 14/01/2026          │
│                                             │
│ 2. Ata de Reunião (#38)                    │
│    12 edições - Última: 13/01/2026          │
│                                             │
│ 3. Memorando Interno (#25)                 │
│    8 edições - Última: 10/01/2026           │
│                                             │
└─────────────────────────────────────────────┘

Relatório de Campos Mais Alterados

Quais campos são alterados com mais frequência:

┌─ Campos Mais Editados ──────────────────────┐
│                                             │
│ 1. Descrição - 234 alterações               │
│ 2. Palavras-chave - 189 alterações          │
│ 3. Nível de Acesso - 78 alterações          │
│ 4. Título - 56 alterações                   │
│ 5. Observações - 43 alterações              │
│                                             │
└─────────────────────────────────────────────┘

Exportação de Logs

Formato CSV

Exportar logs para análise externa:

csv
ID,Data,Usuário,Tipo,Ação,Entidade,Mudanças
log-1,2026-01-14T11:45:00Z,João Silva,DOCUMENT,UPDATE,42,"título: Relatório 2023 → Relatório Anual 2023; acesso: Restrito → Público"
log-2,2026-01-14T10:30:00Z,Maria Santos,DOCUMENT,CREATE,43,
log-3,2026-01-13T16:20:00Z,Admin,FIELD_CONFIGURATION,FIELD_CREATED,field-uuid,"fieldKey: numeroProcesso; label: Número do Processo"

Formato JSON

Exportar logs estruturados:

json
[
  {
    "id": "log-1",
    "timestamp": "2026-01-14T11:45:00Z",
    "user": {
      "id": "user-uuid",
      "name": "João Silva",
      "email": "joao@example.com"
    },
    "entityType": "DOCUMENT",
    "entityId": "42",
    "action": "UPDATE",
    "changes": {
      "title": {
        "old": "Relatório 2023",
        "new": "Relatório Anual 2023"
      },
      "accessLevel": {
        "old": "Restrito",
        "new": "Público"
      }
    }
  }
]

Best Practices

Para Usuários

  1. Sempre preencha descrições: Facilita entender mudanças no histórico
  2. Evite edições em lote: Dificulta rastreamento de mudanças
  3. Revise antes de salvar: Cada salvamento gera log de auditoria

Para Administradores

  1. Monitore logs regularmente: Detecte atividades suspeitas
  2. Configure retenção: Defina política de retenção de logs
  3. Exporte periodicamente: Backup de logs para análise externa
  4. Analise relatórios: Identifique padrões de uso e problemas

Para Desenvolvedores

  1. Sempre crie logs: Toda operação deve gerar auditoria
  2. Use transações: Garanta atomicidade de operação + log
  3. Capture mudanças: Use calculateChanges para diffs precisos
  4. Evite informações sensíveis: Não logue senhas ou tokens

Troubleshooting

Log não foi criado

Causas:

  • Transação falhou antes do commit
  • Erro no createAuditLog
  • Permissões insuficientes

Solução:

  • Verifique logs de erro do servidor
  • Confirme que transação foi commitada
  • Adicione try-catch apropriado

Mudanças não aparecem

Causas:

  • calculateChanges não detectou diferença
  • Campos não foram alterados de fato
  • Comparação de objetos complexos

Solução:

  • Verifique se valores realmente mudaram
  • Use JSON.stringify para comparação profunda
  • Adicione logging de debug

Performance de consulta

Causas:

  • Tabela de auditoria muito grande
  • Falta de índices
  • Queries sem filtros

Solução:

  • Adicione índices em userId, entityId, createdAt
  • Use paginação em consultas
  • Implemente arquivamento de logs antigos

Próxima Etapa

Continue para a seção API Reference para detalhes técnicos da API.

Sistema de Gestão de Arquivos Digitais