Skip to content

History Module (Audit Log) ​

Sistema genérico de histórico de alterações para rastrear mudanças em qualquer entidade.

Conceito ​

Toda alteração (update, mudança de status) grava um snapshot completo da entidade antes da modificação. Isso permite reconstruir o estado da entidade em qualquer ponto no tempo.

Domain Layer ​

Types (src/domain/history/types.ts) ​

TipoDescrição
EntityTypeUnion de entidades rastreáveis: 'contract' | 'template' | 'workflow'
HistoryEntryRegistro de histórico com snapshot completo
HistoryFilterFiltro por entityType + entityId

HistoryEntry ​

CampoTipoDescrição
idstringUUID do registro
entityTypeEntityTypeTipo da entidade alterada
entityIdstringUUID da entidade
datastringJSON.stringify do snapshot completo antes da alteração
updatedBystringUUID do usuário que fez a alteração
updatedAtDateTimestamp da alteração

Constants (src/domain/history/constants.ts) ​

  • ENTITY_TYPES: Mapa de entity types disponíveis

API Endpoints ​

MétodoEndpointDescrição
GET/history?entityType=contract&entityId=:idLista histórico de uma entidade (ordenado por data desc)
POST/historyCria entrada de histórico (uso interno)

GET /history ​

Query params obrigatórios:

  • entityType: Tipo da entidade (contract, template, workflow)
  • entityId: UUID da entidade

Response: HistoryEntry[] ordenado por updatedAt desc

POST /history ​

Body:

json
{
  "entityType": "contract",
  "entityId": "uuid",
  "data": "{...json stringified...}",
  "updatedBy": "user-uuid"
}

Response: HistoryEntry criado (status 201)

Integração com Entidades ​

Para adicionar histórico a uma nova entidade:

  1. Adicionar o tipo em EntityType (src/domain/history/types.ts)
  2. Adicionar a constante em ENTITY_TYPES (src/domain/history/constants.ts)
  3. No handler MSW da entidade, importar addHistoryEntry de src/mocks/handlers/history.ts
  4. Antes de aplicar a mutação (PUT/PATCH), chamar:
    ts
    addHistoryEntry('entity-type', entityId, JSON.stringify(currentEntity), userId)

Exemplo (já implementado em contracts) ​

ts
// src/mocks/handlers/contracts.ts
import { addHistoryEntry } from './history'

// No handler PUT, antes de aplicar as mudanças:
addHistoryEntry('contract', id, JSON.stringify(contracts[index]), userId)

Mock Data ​

Arquivo: src/mocks/data/history.ts

Contém entradas de exemplo para contratos existentes, simulando alterações de status e dados.

Estrutura de Arquivos ​

src/domain/history/
├── types.ts          # HistoryEntry, EntityType, HistoryFilter
├── constants.ts      # ENTITY_TYPES
└── index.ts          # Re-exports

src/mocks/
├── data/history.ts          # Mock data
└── handlers/history.ts      # GET/POST handlers + addHistoryEntry helper

Backend: Orientações para Implementação ​

Tabela sugerida: entity_history ​

ColunaTipoConstraints
idUUIDPK, default gen_random_uuid()
entity_typeVARCHAR(50)NOT NULL, INDEX
entity_idUUIDNOT NULL, INDEX
dataJSONBNOT NULL
updated_byUUIDNOT NULL, FK → users(id)
updated_atTIMESTAMPNOT NULL, default NOW()

Índices recomendados ​

  • idx_entity_history_lookup em (entity_type, entity_id, updated_at DESC)

Trigger ou middleware ​

O registro de histórico deve ser criado antes do UPDATE na entidade principal, capturando o estado atual (pré-alteração). Pode ser implementado via:

  • Trigger de banco (BEFORE UPDATE)
  • Middleware na camada de serviço
  • Interceptor no ORM