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