---
# System prepended metadata

title: Serviço de histórico
tags: [Análise Cloud]

---

---
title: Serviço de histórico
tags: Análise Cloud
---

# Serviço de histórico

A ideia é criar um serviço para persistr o histórico de todos os campos, unindo os campos standards e os personalizados.

Uma request quando chega no heimdall é gerado um id pra ela para podermos identifica-la em qualquer ponto, esse id é passado para as requests internas que fazemos tbm. Sendo assim podemos utilizar esse id para unir os dados de históricos dos serviços standards e do btb.

Basicamente cada serviço fica responsavel por fazer a diff de seus dados e enviar ao serviço de histórico passando o request id que gerou essas diffs, o serviço de histórico por sua vez une todas as diffs que chegarem para a mesma request id. 

## Base de dados

``` sql
CREATE TABLE revision (
    id uuid NOT NULL,
    request_id uuid NOT NULL,
    "date" timestamptz NOT NULL,
    user_id uuid NOT NULL,
    user_name varchar(255) NOT NULL,
    system_version varchar(64) NOT NULL,
    history_type varchar(20) NOT NULL,
    origin varchar(20) NOT NULL,
    "version" int4 NULL,
    updated_at timestamptz NOT NULL,
    created_at timestamptz NOT NULL,
    external_id varchar(255) NULL,
    PRIMARY KEY (id)
);
 
CREATE TABLE entity_state (
    id uuid NOT NULL,
    "version" int4 NULL,
    external_id varchar NULL,
    revision_id uuid NOT NULL,
    previous_entity_state_id uuid NULL,
    sequence_record_changing int4 NOT NULL,
    service varchar(20) NOT NULL,
    event_type varchar(20) NOT NULL,
    entity varchar(100) NOT NULL,
    record_id uuid NOT NULL,
    record_text_identifier varchar(255) NOT NULL,
    state jsonb NOT NULL,
    parent_id uuid NULL,
    parent_name varchar(100) NULL,
    updated_at timestamptz  NOT NULL,
    created_at timestamptz  NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (previous_entity_state_id) REFERENCES entity_state(id)
        ON UPDATE RESTRICT
        ON DELETE RESTRICT,
    FOREIGN KEY (revision_id) REFERENCES revision(id)
        ON UPDATE RESTRICT
        ON DELETE RESTRICT
);

CREATE TABLE history_comment (
    id uuid NOT NULL,
    "comment" varchar(4000) NOT NULL,
    record_id uuid NOT NULL,
    "version" int4 NULL,
    updated_at timestamptz  NOT NULL,
    created_at timestamptz  NOT NULL,
    external_id varchar(255) NULL,
    service varchar(20) NOT NULL,
    entity varchar(80) NOT NULL,
    revision_id uuid NOT NULL,
    deleted bool NOT NULL DEFAULT false,
    PRIMARY KEY (id),
    FOREIGN KEY (revision_id) REFERENCES revision(id)
);
 
CREATE TABLE history_system_event (
    id uuid NOT NULL,
    revision_id uuid NOT NULL,
    event varchar(80) NULL,
    event_type varchar(40) NOT NULL,
    event_args jsonb,
    message varchar(255),
    record_id uuid NOT NULL,
    service varchar(20) NOT NULL,
    entity varchar(80) NOT NULL,
    "version" int4 NULL,
    updated_at timestamptz  NOT NULL,
    created_at timestamptz  NOT NULL,
    external_id varchar(255) NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (revision_id) REFERENCES revision(id)
        ON UPDATE RESTRICT
        ON DELETE RESTRICT
);

```

## API

### Fluxo

```mermaid
sequenceDiagram
    participant Heimdall
    participant Router
    participant Customer
    participant BTB
    participant Mensageria
    participant Historic
    Heimdall->>Router: Adiciona request id
    Router->>Customer: Chama serviço standard
    Customer->>Customer: Recebe dados standards, gera o diff deles e persiste no banco local
    Customer->>Mensageria: Envia mensagem com o id do registro de histórico que deve ser consultado
    Router->>BTB: Chama o btb
    BTB->>BTB: Recebe dados personalizados, gera o diff deles e persiste no banco local
    BTB->>Mensageria: Envia mensagem com o id do registro de histórico que deve ser consultado
    Historic->>Mensageria: Consulta mensagns a serem processadas
    Historic->>Customer: Consulta registro de histórico com o id passado na mensagem
    Historic->>Historic: Persiste o registro de histórico cos campos standards
    Historic->>BTB: Consulta registro de histórico com o id passado na mensagem
    Historic->>Historic: Atualiza o registro de histórico dos campos standards fazendo merge com os campos customizados
```

### Post de histórico

*/histories/{service}/{entity}/*

```jsonql=
{
    "revision": {
        "requestId": "",
        "date": "",
        "userId": "",
        "userName": "",
        "systemVersion": "",
        "historyType": "",
        "origin": "",
        "entityStaties": [{
            "externalId": "",
            "revisionId": "",
            "previousEntityStateId": "",
            "sequenceRecordChanging": "",
            "eventType": "",
            "recordId": "",
            "recordTextIdentifier": "",
            "state": {},
            "parentId": "",
            "parentName": "",
        }]
}
```

Ao receber esses dados deve ser verificado se ja existe uma revisão para o registro, caso não exista deve ser persistido os registros, caso contrário deve ser apenas mergeado o state unindo os dados.

Para verificar se um registro existe deve ser utilizado as seguinte informações:

* requestId
* service
* entity
* recordId

### Post de comentários

Comentários geram uma revisão própria e são vinculados à uma entidade através de seu Id

*/comments/{service}/{entity}/{recordId}*

```jsonql=
{
    "historyComment":   {
        "comment":   "Este é um exemplo de comentário de oportunidade."
    }
}
```

### Get

Lista todos os acontecimentos relacionados à um entidade específica, estes acontecimentos são:

-   Auditorias
-   Comentários
-   Eventos de Sistema


*/histories/{service}/{entity}/{recordId}*

```jsonql=
{
    "items": [
        {
            "user": {
                "id": "27801f26-9bef-4bc1-b5bc-ee922499dd59",
                "name": "Administrador"
            },
            "date": "2019-01-11T20:14:23.503Z",
            "historyType":   "AUDIT"
        }
    ],
    "count": 1,
    "firstRow": 0,
    "page": 0,
    "pageSize":1
    }
```

## Audit

A proposta é alterar a lib existente [audit](https://gitlab.wssim.com.br/cloud/audit) hoje para que ao invés de persistir os registros essa lib deve gerar as mensagens com as diffs para que o serviço de histórico consuma e persista.

Além disso parte do que essa lib faz hoje o serviço de histórico que irá fornecer tirando essas responsabilidades da lib, sendo elas:

* End point de comentários (que hoje fica em [Histories](https://gitlab.wssim.com.br/cloud/audit#gerando-coment%C3%A1rios))
* End point de pesquisa ([Search](https://gitlab.wssim.com.br/cloud/audit#filtros))

### End-points para accesso do histórico

Fica como responsabilidade do audit expor end-point que seja possivel configurar (via desenvolvimento) e expor para acesso do usuario os registros do histório

### Sync

Para registros que venham de mobile o histórico deve ser gerado a partir da sync. Para esses casos o id da sync deve ser utilizado como request id ja que os serviços são sincronizados na mesma request.

Comentários podem ser criados no mobile e sincronizados normalmente.

A sync deve ser feita a partir do serviço da entidade, ou seja, vai ser um proxy para o histórico. Isso para poder ser aplicado os fitros corretos de sincronização.

## Serviços standards

Os serviços deverão implementar a lib audit que fará a auditoria e enviará os dados para o serviço de histórico.

Alem de servirem como proxy para manipular comentários e consultar os resgistros de histórico.

### Telas

As telas ficam por responsabilidade de cada serviço implementar e exibir os registros de histórico da melhor forma para o contexto de cada funcionalidade.

Atualmente existe um componente responsavel por fazer isso. Esse componente deve ser alterado para possibilitar a exibição de campos personalizados.

Hoje esse componente somente internacionaliza os nomes dos campos conforme passado para ele, ele deve passar a verificar se é um campo que standard e nesse caso internacionalizar, caso contrario assumir o label passado para ele.

### Serviços com histórico ja implementados

Será nescessário replicar todos os registros. Como as entidades são basicamente a mesma não deve ser um problema porém deve-se tomar cuidado para migrar a qual serviço pertence o registro.

## BTB

No primeiro momento o BTB vai gerar apenas histórico do data lake de entidade standards, ou seja, não será gerado histórico de alteração de metada dados e nem histórico de entidades customs.

Para isso o btb irá enviar as alterações de data lake utilizando o serviço e nome da entidade standard.

O BTB irá utilizar uma lib nossa pra fazer a diff do JSON, após isso iremos converter o resultado retornado dessa lib na estrutura esperada pelo Javers e persistir. A partir desse ponto segue o mesmo fluxo que serviços standards, ou seja, gera uma mensagem para o serviço centralizador consumir.