> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Como o Lerian SISBAJUD executor executa ordens

> Como o Lerian SISBAJUD executor recebe avisos de execução, executa bloqueios, desbloqueios e requisições de informação no Midaz, e informa cada resultado à Mensageria.

O **executor** executa as ordens judiciais da Mensageria no ledger Midaz da instituição. Esta página descreve como o executor recebe uma ordem, o que cada operação escreve e como o executor informa o resultado. [Operando o Lerian SISBAJUD executor](/pt/rails/sisbajud/sisbajud-executor-operations) descreve a configuração.

<h2 id="order-lifecycle">
  Ciclo de vida da ordem
</h2>

***

1. **Aviso.** O Streaming Hub envia um aviso de execução ao listener de webhook do executor. O aviso traz o ID da ordem e a revisão da ordem, não a ordem.
2. **Verificação.** O executor verifica a assinatura HMAC da entrega. Ele grava cada aviso assinado antes de responder.
3. **Busca.** O executor obtém a ordem com `GET /v1/sisbajud/execution/orders/{orderId}` na API de execução da Mensageria.
4. **Verificação do dono.** Antes da sua primeira escrita, o executor verifica que é dono da instituição da ordem.
5. **Execução.** No seu próximo ciclo, o executor executa a operação no Midaz.
6. **Resultado.** O executor envia o resultado com `POST /v1/sisbajud/execution/orders/{orderId}/execution-results`.

### Respostas do webhook

| Entrega | Resposta |
| - | - |
| O corpo é maior que 1 MiB. | `413`. O executor não grava nada. |
| Nenhuma assinatura é válida. | `401`. O executor não grava nada. |
| A assinatura é válida, mas o corpo não é um aviso utilizável. | `200`. O executor estaciona a entrega e dispara um alarme. |
| A Mensageria ou um banco de dados falha. | `503`. O Streaming Hub tenta a entrega de novo. |
| O executor aceita o aviso. | `200`. O executor executa a ordem no seu próximo ciclo. |

O executor aceita uma entrega com timestamp fora de `EXECUTOR_HUB_WEBHOOK_MAX_SKEW_SEC` e registra um aviso no log.

### Respostas da busca

| Resposta da Mensageria | O que o executor faz |
| - | - |
| `200` | Executa a ordem. |
| `404` ou `410` | Trata a ordem como retirada. Ele não escreve nada no ledger. |
| `401`, `429`, um status `5xx` ou um erro de rede | Tenta a requisição de novo. |
| Qualquer outro status `4xx` | Estaciona a entrega e dispara um alarme. |

### Verificação do dono

O executor escreve no ledger somente para as instituições das quais é dono. Quando cria uma instituição, ele registra o seu próprio subject M2M (`EXECUTOR_M2M_SUBJECT`) como dono.

* Se outra identidade é dona da instituição, o executor não escreve nada e dispara um alarme.
* Se a instituição não tem configuração neste executor, a ordem vai para uma decisão humana.

### Ciclo de execução

O executor executa um ciclo a cada `EXECUTOR_TICK_EVERY`. O padrão é `30s`. Cada ciclo executa quatro etapas nesta ordem:

1. **Ingestão.** Executa os avisos aceitos.
2. **Verificação de órfãs.** Procura operações nas contas de bloqueio que o executor não escreveu.
3. **Monitoramento.** Envia um heartbeat para cada escrita que não tem resultado conhecido.
4. **Drenagem.** Envia os resultados que esperam no outbox.

Uma etapa com falha não interrompe as outras etapas.

### Resultados

O executor grava cada resultado em um outbox antes de enviá-lo. Cada envio traz o header `X-Idempotency`. Quando um envio falha com um erro transitório, o executor envia o mesmo resultado de novo em um ciclo posterior.

| Campo | Valores |
| - | - |
| `executionState` | `ACCEPTED`, `EXECUTING`, `MONITORING`, `RESOLVED`, `INDETERMINATE`, `AWAITING_RECONCILIATION` |
| `effect` | `NONE`, `FULL`, `PARTIAL`, `INDETERMINATE` |

O `reasonCode` de cada operação está nas seções abaixo.

<h2 id="operations">
  Operações
</h2>

***

O executor executa três operações. O bloqueio e o desbloqueio escrevem no Midaz. A requisição de informação somente lê.

<h3 id="block">
  Bloqueio (BLOQUEIO)
</h3>

1. O executor lê as contas ativas do sujeito. Um sujeito sem conta ativa recebe `NONE` com `NO_CLIENT`.
2. Ele aplica a restrição de agência e conta da ordem.
3. Ele bloqueia uma conta salário somente quando a ordem permite contas salário.
4. Ele bloqueia somente recursos próprios. Uma conta no cheque especial conta como 0.
5. Ele envia uma escrita ao Midaz. A escrita tem uma perna para cada conta de origem, e todas as pernas vão para a conta de bloqueio da ordem.

| Resultado | `effect` | `reasonCode` |
| - | - | - |
| O bloqueio cobre o valor ainda aberto na ordem. | `FULL` | `BLOCKED_TOTAL` |
| O bloqueio cobre menos que esse valor. | `PARTIAL` | `BLOCKED_PARTIAL` |
| Não há recursos disponíveis. | `NONE` | `NO_BALANCE` |

<h3 id="unblock">
  Desbloqueio (DESBLOQUEIO)
</h3>

O desbloqueio libera recursos de uma ordem de bloqueio pai, identificada por `parentOrderId`.

* Sem uma ordem pai, o resultado é `NONE` com `PARENT_UNRESOLVED`, e o executor não escreve nada.
* Quando a ordem pai ainda não tem efeito conhecido, o executor espera. No prazo da ordem, ele entrega a ordem a uma decisão humana.
* O executor lê a conta de bloqueio da ordem pai quando executa a ordem. Ele libera o menor de três valores: o valor que a ordem pede, o saldo restante da ordem pai e o saldo da conta de bloqueio.
* Quando o valor a liberar é 0, o resultado é `NOTHING_TO_RELEASE`.
* O executor devolve os recursos a cada conta de origem do bloqueio pai.
* Quando uma conta do sujeito é uma conta salário, a ordem vai para uma decisão humana.

<h3 id="information-request">
  Requisição de informação (REQUISICAO\_INFORMACAO)
</h3>

O executor lê os saldos do sujeito e não escreve nada no ledger. Ele responde dois totais: o total bloqueável e o total bloqueável das contas salário.

* Um sujeito com pelo menos uma conta ativa recebe `FULL` com `INFO_FULFILLED`.
* Um sujeito sem conta ativa recebe `NONE` com `INFO_NON_CLIENT`.
* Uma ordem que indica uma agência vai para uma decisão humana.
* Uma ordem que indica uma conta que o sujeito não tem vai para uma decisão humana.

<h2 id="ledger-semantics">
  Semântica do ledger
</h2>

***

### Conta de bloqueio

Cada ordem de bloqueio tem a sua própria conta de bloqueio no Midaz. O alias da conta de bloqueio tem o prefixo `@block_sisbajud_` e depois os 32 dígitos hexadecimais minúsculos do ID da ordem de bloqueio. Um desbloqueio encontra a conta pelo seu `parentOrderId`.

O tipo de conta de uma conta de bloqueio é `sisbajud_block`. Se o seu ledger valida tipos de conta, registre `sisbajud_block` como tipo de conta.

### Direções

* Um bloqueio diminui as contas do sujeito e aumenta a conta de bloqueio.
* Um desbloqueio diminui a conta de bloqueio. A escrita dele tem uma perna de origem: a conta de bloqueio.

Um bloqueio move o valor do saldo disponível de cada conta do sujeito para o saldo disponível da conta de bloqueio.

### Idempotência

Cada escrita traz o header `X-Idempotency` e `X-TTL: 604800`, que são sete dias. O Midaz guarda a chave de idempotência de uma escrita por esse tempo. A chave é `orderId:orderRevision`. Uma reentrega da mesma revisão da ordem envia a mesma chave.

<h2 id="uncertain-writes">
  Escritas incertas
</h2>

***

Quando o Midaz responde a uma escrita sem prova do seu efeito, o resultado é `INDETERMINATE`. O executor lê o ledger de novo antes de cada heartbeat. Ele envia um resultado de heartbeat à Mensageria a cada `EXECUTOR_HEARTBEAT_EVERY`.

A ordem vai para uma decisão humana no primeiro de dois limites:

* `EXECUTOR_HUMAN_DECISION_AFTER_BEATS` heartbeats sem mudança. O padrão é 3.
* O prazo da ordem menos `RESPONSE_DEADLINE_MARGIN`.

O executor então registra uma decisão humana. Na lista de decisões humanas, ela tem `humanDisposition` `HELD_MONEY_MOVED`, e o executor não envia nenhuma resposta final. Os heartbeats continuam, com `executionState` e `effect` ambos `INDETERMINATE`.

### Operações que o executor não escreveu

A verificação de órfãs lê as operações de cada conta de bloqueio ao longo de `EXECUTOR_ORPHAN_RECONCILE_WINDOW`. O padrão é `48h`. O executor informa uma operação como órfã quando a sua transação não tem `metadata.code`, ou tem um código que o executor não registrou. Esta etapa somente detecta. Ela não muda nada no ledger.

<h2 id="accounting-routes">
  Rotas contábeis
</h2>

***

As rotas contábeis são opcionais, por organização. O executor as lê dos documentos de tenant `routing.organizations` e `routing.ledger_bindings` no Systemplane. Com `SYSTEMPLANE_ENABLED` desligado, o executor escreve sem rotas.

Quando uma escrita não pode sair por causa da sua configuração, o executor a adia. O Midaz não aplicou nada, então a ordem espera, e uma entrega posterior envia a mesma escrita com a mesma chave de idempotência. Estas condições adiam uma escrita:

* O executor não consegue resolver as rotas contábeis da escrita.
* O Midaz recusa as rotas contábeis da escrita: `422` com código `0113`, `0114`, `0116`, `0117`, `0118`, `0119`, `0152` ou `0157`, ou `404` com código `0105`.

Corrija a configuração antes do prazo da ordem. `GET /v1/admin/ledger-routing/preflight` verifica a configuração antes de você ligar as rotas.

<h2 id="midaz-calls">
  Chamadas ao Midaz
</h2>

***

O executor chama o ledger Midaz no `baseUrl` de cada instituição, com o token dessa instituição. Dê às credenciais da instituição acesso a estas operações:

| Finalidade | Operação do Midaz |
| - | - |
| Bloqueio | `POST /v1/organizations/{organizationId}/ledgers/{ledgerId}/transactions/block` |
| Desbloqueio | `POST /v1/organizations/{organizationId}/ledgers/{ledgerId}/transactions/unblock` |
| Criar uma conta de bloqueio | `POST /v1/organizations/{organizationId}/ledgers/{ledgerId}/accounts` |
| Encontrar uma conta pelo alias | `GET /v1/organizations/{organizationId}/ledgers/{ledgerId}/accounts?alias=` |
| Ler uma conta | `GET /v1/organizations/{organizationId}/ledgers/{ledgerId}/accounts/{accountId}` |
| Ler os saldos de um alias | `GET /v1/organizations/{organizationId}/ledgers/{ledgerId}/accounts/alias/{alias}/balances` |
| Ler as operações de uma conta de bloqueio | `GET /v1/organizations/{organizationId}/ledgers/{ledgerId}/accounts/{accountId}/operations` |
| Ler uma transação | `GET /v1/organizations/{organizationId}/ledgers/{ledgerId}/transactions/{transactionId}` |
| Encontrar as transações de uma escrita | `GET /v1/organizations/{organizationId}/ledgers/{ledgerId}/transactions?metadata.code=` |

O executor encontra as contas de um sujeito pelo CRM do Midaz. Com `crmMode` `legacy`, ele chama `GET /v1/aliases?document=` em `crmBaseUrl`. Com `crmMode` `embedded`, ele chama `GET /v2/organizations/{organizationId}/instruments?document=` em `baseUrl`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.