> ## 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.

# Operando o Plugin SISBAJUD

> Configure e opere o Plugin SISBAJUD: instituições e o seu conector do Midaz, o canal direto, roteamento do ledger, ordens que precisam de atenção, rotação da chave de credenciais, papéis, listeners e restrições de deploy.

Esta página descreve como configurar e operar o **Plugin SISBAJUD**. [Operando o Lerian SISBAJUD](https://docs.lerian.studio/pt/rails/sisbajud/sisbajud-operations.md) descreve a Mensageria. [Como o Plugin SISBAJUD executa ordens](https://docs.lerian.studio/pt/interfaces/plugin-sisbajud/plugin-sisbajud-how-it-works.md) descreve o que o plugin faz com cada ordem.

## Configuração da instituição

***

Registre cada instituição na Mensageria e no plugin, com o mesmo `institutionId`. [Operando o Lerian SISBAJUD](https://docs.lerian.studio/pt/rails/sisbajud/sisbajud-operations.md#institutions) descreve a requisição da Mensageria.

`POST /v1/institutions` registra uma instituição no plugin. O corpo tem estes campos:

| Campo | Significado |
| - | - |
| `institutionId` | O UUID da instituição. Use o mesmo valor da Mensageria. |
| `connectorType` | O conector do ledger. Defina-o como `midaz`. |
| `institutionCode` | A raiz do CNPJ da instituição, com 8 dígitos. |
| `enabled` | Se a instituição está ativa. Envie `true`. |
| `connectorMetadata` | A configuração do Midaz da instituição. As tabelas abaixo a descrevem. |
| `retryPolicyConfig` | Opcional. A política de retentativa, em JSON. |
| `branchFormat` | Opcional. Uma expressão regular Go RE2, com no máximo 64 caracteres, para o número da agência que um tribunal pode indicar em uma restrição de bloqueio. |
| `accountFormat` | Opcional. Uma expressão regular Go RE2, com no máximo 64 caracteres, para o número da conta que um tribunal pode indicar em uma restrição de bloqueio. O plugin compara esse número com `bankingDetails.account` dos instrumentos do CRM, então a restrição exige `crmMode` `embedded`. |

A requisição também cria o keyset de tokenização e o keyset de auditoria da instituição. Uma segunda requisição com o mesmo `institutionId` retorna `409`.

O plugin se registra como dono da instituição, a partir da sua própria identidade M2M (`EXECUTOR_M2M_SUBJECT`). Nenhum campo de requisição define o dono, e um `PATCH` não o altera.

### Metadados do conector

| Chave | Obrigatório | Significado |
| - | - | - |
| `organizations` | Sim | Uma lista de entradas `{organizationId, ledgers}`: as organizações do Midaz em que o plugin procura as contas de um sujeito. Sem `ledgers`, o plugin procura em todos os ledgers da organização. |
| `baseUrl` | Sim | A URL base do ledger Midaz da instituição. |
| `authAddress` | Quando há credenciais gravadas | O endereço do Access Manager que emite o token do Midaz da instituição. |
| `blockableBalances` | Sim | As chaves de saldo do Midaz que um bloqueio pode usar, por exemplo `default`. São chaves de saldo, não os valores `available` ou `onHold`. |
| `blockableAccountTypes` | Sim | Os tipos de conta que um bloqueio pode usar. |
| `salaryAccountTypes` | Sim | Os tipos de conta que são contas salário. Envie `["NONE"]` quando a instituição não tem tipo de conta salário. |
| `crmMode` | Não | `legacy` ou `embedded`. Sem valor, a instituição usa `MIDAZ_CRM_MODE`. |
| `crmBaseUrl` | Não | A URL base do CRM autônomo do Midaz, para `legacy`. Com `embedded`, deixe-a vazia: o plugin lê o CRM pelo `baseUrl`. |
| `permanentProducts` | Para gravar resultados de bloqueio permanente | O catálogo de produtos da instituição: `bankCode` e, em `types`, a classe e o código do produto de cada tipo de conta. Sem ele, o plugin retém o resultado de um bloqueio posterior e dispara um alarme. |
| `executorLedger` | Para executar ordens | O ledger em que o plugin escreve. A próxima tabela o descreve. |

### Ledger do plugin

| Chave | Significado |
| - | - |
| `organizationId` | A organização do Midaz das escritas. |
| `ledgerId` | O ledger do Midaz das escritas. |
| `asset` | Defina-o como `BRL`, exatamente. |
| `judicialDepositAccountAlias` | O alias da conta de depósito judicial. Ele deve seguir a regra de alias do Midaz. |

O plugin recusa uma requisição de instituição cujo `executorLedger` está presente e não é válido, com `400`. Na inicialização, o plugin deixa fora do seu roteamento do ledger uma instituição que não tem `executorLedger` válido.

### Credenciais do conector

`PUT /v1/institutions/{institutionId}/connector-credentials` grava as credenciais do Midaz da instituição:

* `ledger_client_id` e `ledger_client_secret` são sempre obrigatórios.
* `crm_client_id` e `crm_client_secret` são obrigatórios com `crmMode` `legacy`. Com `embedded`, não os envie.

O plugin criptografa as credenciais antes de gravá-las. `PATCH /v1/institutions/{institutionId}` recusa um corpo com credenciais. Uma nova credencial não revoga a anterior no Access Manager, então revogue-a lá.

O plugin obtém o token do Midaz da instituição em `{authAddress}/v1/login/oauth/access_token`. Quando a instituição não tem credenciais gravadas, o plugin não envia header `Authorization` ao Midaz.

### Alterar a configuração

* `PATCH /v1/institutions/{institutionId}` altera os campos da instituição. Um `connectorMetadata` no corpo substitui o pacote inteiro, exceto as credenciais gravadas.
* `PUT /v1/institutions/{institutionId}/connector-config` substitui `connectorType` e `connectorMetadata`. Ele mantém as credenciais gravadas e recusa um corpo com credenciais.
* `GET /v1/institutions/{institutionId}` retorna a configuração sem as credenciais.

O plugin lê a configuração das suas instituições na inicialização. Depois de criar uma instituição ou alterar a sua configuração, reinicie o plugin.

## Canal direto

***

[Como o Plugin SISBAJUD executa ordens](https://docs.lerian.studio/pt/interfaces/plugin-sisbajud/plugin-sisbajud-how-it-works.md#direct-channel) descreve o canal. Para colocar uma instituição nele, envie `PUT /v1/institutions/{institutionId}/channel` com `DIRECT`. Envie `MENSAGERIA` para devolvê-la. A chamada responde `200` com `changed` `false` quando a instituição já está nesse canal.

O canal exige `PLUGIN_AUTH_ENABLED` ligado, um tenant e o modo executor. A troca exige uma pessoa com o papel `platform-admin`. O plugin recusa um token de aplicação e um token com escopo de tenant com `403`.

A troca recusa com estes códigos:

* `SBJ-0040` / **422**: o deploy é multi-tenant.
* `SBJ-0041` / **422**: `PLUGIN_AUTH_ENABLED` está desligado.
* `SBJ-0042` / **422**: o código da instituição guardado não é a raiz de 8 caracteres do CNPJ do agrupamento responsável.
* `SBJ-0043` / **409**: a instituição tem uma ordem aberta, ou um bloqueio que ainda retém dinheiro.
* `SBJ-0046` / **409**: outra troca venceu. Nada se moveu. Envie a requisição de novo.
* `SBJ-0060` / **409**: outra instalação do Plugin SISBAJUD é dona da instituição.

### Apagar uma ordem do canal direto

Um administrador da plataforma chama duas rotas para apagar ordens do canal direto. [Como o Plugin SISBAJUD executa ordens](https://docs.lerian.studio/pt/interfaces/plugin-sisbajud/plugin-sisbajud-how-it-works.md#direct-channel) descreve o que um apagamento remove e o que ele mantém.

* `POST /v1/admin/direct/orders/{orderId}/erase` apaga uma ordem. O corpo traz `reason`, `ticket` e um `note` opcional. `reason` é `lgpd-subject-request` ou `retention-purge`. `ticket` tem até 64 caracteres, e `note` tem até 256. Nenhum deles pode conter dados pessoais. A resposta é `200` com `outcome` `erased`, ou `noop` quando a ordem já está apagada, e o número de linhas apagadas.
* `POST /v1/admin/direct/purge` lista as ordens que já podem ser apagadas e não muda nada. O corpo traz `reason`, `ticket`, `limit` (de 1 a 100, e 100 quando ausente) e `dryRun`, que deve ser `true`. A resposta traz `orderIds`, da mais antiga para a mais nova, `asOf` e `truncated`. `truncated` é `true` quando a lista parou antes de o plugin ler todos os candidatos.

O chamador precisa do token de uma pessoa, sem tenant. O plugin recusa um token de aplicação com `403` `SBJ-0044`, e um token com escopo de tenant com `403` `SBJ-0045`. As rotas só existem quando o plugin roda em modo executor com `PLUGIN_AUTH_ENABLED` ligado. Um deploy multi-tenant recebe `422` `SBJ-0059`. Uma ordem desconhecida recebe `404` `SBJ-0015`. A [lista de erros do Plugin SISBAJUD](https://docs.lerian.studio/pt/reference/interfaces/plugin-sisbajud/plugin-sisbajud-error-list.md) lista `SBJ-0056` a `SBJ-0059`.

O gauge `sisbajud_executor_direct_intake_purge_eligible` conta as ordens que já podem ser apagadas. A contagem é um limite inferior. `EXECUTOR_DIRECT_PURGE_REFRESH_EVERY` define a frequência com que o plugin conta.

## Roteamento do ledger

***

Com `SYSTEMPLANE_ENABLED` ligado, o plugin serve os documentos de tenant das suas rotas contábeis em `/tenant-system`. O plugin lê dois deles: `routing.organizations` liga as rotas contábeis de cada organização, e `routing.ledger_bindings` guarda as rotas. Com `SYSTEMPLANE_ENABLED` desligado, o plugin escreve sem rotas.

`routing.organizations` aceita `schemaVersion` 1 ou 2. Com `schemaVersion` 2, cada entrada de organização tem as suas próprias `routes` para cada fluxo e os seus `ledgers`, os ledgers que lançam com essas rotas. O plugin então não lê `routing.ledger_bindings`, e uma escrita em um ledger fora de `ledgers` sai sem rotas.

`GET /v1/admin/ledger-routing/preflight` verifica a configuração de roteamento em relação ao ledger da instituição. Ele não escreve nada. Um plugin single-tenant precisa do parâmetro de consulta `institutionId`. O relatório cobre estas verificações:

* As rotas de transação e as rotas de operação existem e correspondem às escritas do plugin.
* Um ledger que valida tipos de conta tem `sisbajud_block` registrado.
* A conta de depósito judicial em `executorLedger` existe no ledger e não está bloqueada.
* Com `schemaVersion` 2, o ledger de cada escrita está nos `ledgers` da sua organização. Um ledger fora da lista recebe o problema `ledger_not_listed`, e o documento de bindings recebe o estado `ignored`.

O campo `ready` informa se a configuração está pronta. O relatório mostra o `executorLedger` gravado. O plugin em execução usa a configuração que leu na inicialização.

## Ordens que precisam de atenção

***

| Operação | O que retorna |
| - | - |
| `GET /v1/institutions/{institutionId}/executor/failed-orders` | As revisões de ordem que o plugin falhou ou abandonou. Cada item tem o ID da ordem, a revisão, um token de motivo e o ID da sua entrada no journal. Ele não lista as revisões cujo resultado ainda não é conhecido. |
| `GET /v1/institutions/{institutionId}/executor/human-decisions` | As revisões de ordem que o plugin parou em uma decisão humana. |

Cada decisão humana tem um `humanDisposition`:

* `GAVE_UP`: o plugin não tentou nenhuma escrita no ledger e respondeu `EXECUTOR_GAVE_UP`.
* `HELD_MONEY_MOVED`: o plugin tentou uma escrita. O dinheiro pode ter se movido, e o plugin não enviou resposta.

O plugin também registra uma decisão humana quando estaciona um resultado depois de `EXECUTOR_RESULT_MAX_ATTEMPTS` envios com falha, e quando o ledger está fora do ar no corte de uma ordem. [Como o Plugin SISBAJUD executa ordens](https://docs.lerian.studio/pt/interfaces/plugin-sisbajud/plugin-sisbajud-how-it-works.md#ledger-down-at-the-cut) descreve o corte.

### Resolver uma decisão humana

`POST /v1/admin/executor/orders/{orderId}/revisions/{revision}/human-decision/resolution` fecha a decisão humana aberta de uma revisão de ordem. O corpo traz o `decisionId` da decisão, um `reason` e uma `resolution`:

* `proven-no-effect`: o ledger mostra que as escritas da revisão não chegaram.
* `effect-acknowledged`: você aceita o efeito como ele é. Para uma liberação cujo bloqueio pai chegou sem as suas pernas de origem, envie `movedAmount` e uma transação como `ledgerEvidence`.

`ledgerEvidence` é obrigatório quando a revisão é incerta. O `reason` tem no máximo 200 caracteres e nenhum dado pessoal.

O plugin registra a resolução e a sua entrada de auditoria em uma transação. Ele não envia nada ao tribunal: a instituição responde ao tribunal. A rota exige `PLUGIN_AUTH_ENABLED` ligado e uma pessoa com o papel `platform-admin`, e o plugin recusa um token de aplicação e um token com escopo de tenant com `403`. Um deploy multi-tenant responde `422` `SBJ-0053`.

A rota pode retornar estes erros:

* `SBJ-0051` / **409**: a revisão não tem decisão humana aberta para resolver aqui.
* `SBJ-0052` / **422**: a resolução, o motivo ou a evidência não é válido.
* `SBJ-0054` / **409**: o journal mostra que o dinheiro se moveu, então `proven-no-effect` é recusado. Um reconhecimento também é recusado enquanto a escrita está indeterminada.
* `SBJ-0055` / **409**: o journal não mostra efeito concretizado, então não há nada a reconhecer.
* `SBJ-0064` / **409**: a evidência é uma transação que o próprio plugin registrou para a revisão.

### Rearmar um resultado estacionado

`POST /v1/admin/executor/orders/{orderId}/revisions/{revision}/results/{executionVersion}/rearm` pega um resultado que o plugin estacionou em `EXECUTOR_RESULT_MAX_ATTEMPTS`. Ele volta as tentativas para 0, e o plugin envia o resultado de novo na hora. As versões posteriores da mesma ordem então seguem. Envie um `reason` de no máximo 200 caracteres, sem dados pessoais.

Um resultado que está pendente mas não estacionado responde `200` com o resultado `NOOP`. A rota exige `PLUGIN_AUTH_ENABLED` ligado e uma pessoa com o papel `platform-admin`, e funciona apenas em um deploy single-tenant.

* `SBJ-0048` / **409**: o resultado é terminal. Não há nada a rearmar.
* `SBJ-0049` / **422**: o motivo falta, está em branco, é longo demais ou tem dados pessoais.
* `SBJ-0050` / **422**: o deploy é multi-tenant.

### Resolver uma tentativa permanente estacionada

`POST /v1/admin/executor/orders/{orderId}/permanent-attempts/{attemptId}/resolution` resolve uma tentativa estacionada de um bloqueio permanente no canal direto. Ela segue as regras da resolução de decisão humana e exige o mesmo papel e `PLUGIN_AUTH_ENABLED` ligado. Com `proven-no-effect`, os novos créditos do bloqueio voltam a ser tomados. Com `effect-acknowledged`, o plugin conta `movedAmount` no valor da ordem. Ela acrescenta estes erros:

* `SBJ-0061` / **409**: a tentativa não está estacionada, ou a ordem está ocupada.
* `SBJ-0062` / **422**: o valor reconhecido é maior que o que o bloqueio permanente aberto ainda retém, ou maior que a escrita que o plugin registrou para um bloqueio fechado.

A Mensageria também lista as ordens das quais o plugin desistiu. [Operando o Lerian SISBAJUD](https://docs.lerian.studio/pt/rails/sisbajud/sisbajud-operations.md#orders-that-need-attention) descreve essa lista.

## Rotação da chave de credenciais

***

`POST /v1/institutions/{institutionId}/security/credential-kek:rotate` rotaciona a chave que envolve as credenciais do Midaz gravadas da instituição. Essa chave não é a chave de dados da instituição que a Mensageria rotaciona.

* A rotação move as credenciais gravadas para a nova versão da chave. Os valores das credenciais não mudam. Para substituir uma credencial, use `PUT /v1/institutions/{institutionId}/connector-credentials`.
* A resposta mostra a versão anterior e a nova versão da chave.
* Uma instituição sem credenciais gravadas retorna `404`.
* Com `STREAMING_ENABLED` ligado, a rotação publica um evento `kek.rotated` com `keyPurpose` `CREDENTIALS`.
* Com o AWS KMS no modo `provided`, o plugin não rotaciona a sua chave, e a operação retorna `422`.

A rotação pode retornar estes erros:

* `SBJ-0007` / **409**: outra rotação da mesma instituição está em andamento. Envie-a novamente depois que essa rotação terminar.
* `SBJ-0012` / **409**: nada foi rotacionado, e a mesma requisição falha de novo.
* **503**: o gerenciador de chaves falhou antes da rotação. Envie-a novamente mais tarde.
* `SBJ-0013` / **500**: o resultado da rotação não é conhecido. Não envie a rotação novamente.
* `SBJ-0014` / **500**: a chave foi rotacionada, mas uma etapa posterior falhou. Não envie a rotação novamente. Fale com o suporte da Lerian.

Com `PLUGIN_AUTH_ENABLED` desligado, o plugin não serve esta operação.

## Verificação de auditoria

***

`GET /v1/admin/audit/verify` verifica um intervalo do log de auditoria da instituição, de `fromIndex` a `toIndex`. Ele não descriptografa nenhum payload. Ele informa adulterações e entradas apagadas.

## Papéis

***

Cada operação precisa de uma permissão:

| Operação | Permissão |
| - | - |
| Criar ou atualizar uma instituição, a sua configuração de conector ou as suas credenciais | `institution_config:write` |
| Ler uma instituição, as ordens com falha, as decisões humanas ou a verificação de auditoria | `admin:read` |
| Rotação da chave de credenciais | `credential_kek:rotate` |
| Preflight do roteamento do ledger, e leituras em `/tenant-system` | `tenant_policy:read` |
| Escritas em `/tenant-system` | `tenant_policy:write` |
| Trocar o canal de uma instituição | `institution_channel:write` |
| Rearmar um resultado estacionado | `executor_result:rearm` |
| Resolver uma decisão humana ou uma tentativa permanente estacionada | `executor_human_decision:resolve` |
| Apagar uma ordem do canal direto | `direct_order_erasure:erase` |
| Pré-visualizar a limpeza das ordens do canal direto | `direct_order_erasure:purge_preview` |
| Enviar uma ordem direta | `order:submit` |
| Ler ordens e resultados diretos | `result:read` |

O plugin declara os papéis `viewer`, `operator`, `investigator`, `cross-org-reader`, `admin`, `platform-admin`, `order-submitter` e `result-reader`. Cada um dos seis primeiros papéis vincula o grupo `plugin-br-sisbajud-<role>-group`, e `admin` também vincula `admin-group`. Os papéis `order-submitter` e `result-reader` não vinculam nenhum grupo. A sua aplicação M2M tem `admin`, `order-submitter` e `result-reader`.

O papel `admin` tem as permissões das cinco primeiras linhas da tabela. Os papéis `viewer`, `operator`, `investigator` e `cross-org-reader` têm `admin:read`. O papel `platform-admin` tem `institution_channel:write`, `executor_result:rearm`, `executor_human_decision:resolve`, `direct_order_erasure:erase`, `direct_order_erasure:purge_preview` e as permissões `systemplane` de `/system`. Nenhum outro papel as tem. O plugin recusa um token de aplicação e um token com escopo de tenant nas cinco operações de plataforma com `403`.

O papel `result-reader` tem apenas `result:read`. O papel `order-submitter` tem `order:submit`, `result:read` e `metadata:read`. Apenas um chamador com `metadata:read` lê o `metadata` da ordem nas leituras diretas.

### O plugin na Mensageria

O plugin chama a API de execução da Mensageria com o seu próprio cliente M2M. Defina o cliente em `MENSAGERIA_CLIENT_ID` e `MENSAGERIA_CLIENT_SECRET`. O plugin obtém o seu token do Access Manager em `PLUGIN_AUTH_HOST`.

## Listeners

***

O plugin tem dois listeners:

* **API principal**, em `SERVER_ADDRESS`. Defina-o como `:4029`, a porta que a imagem expõe. Ela serve as operações da referência da API. Ela também serve `/health`, `/readyz` e `/version`. Com `SYSTEMPLANE_ENABLED` ligado, ela serve `/system` e `/tenant-system`. Com `SWAGGER_ENABLED` ligado, ela serve `/swagger`.
* **Listener de webhook**, em `EXECUTOR_HUB_WEBHOOK_ADDRESS`. O padrão é `:9082`. Ele tem uma rota, `POST` em `EXECUTOR_HUB_WEBHOOK_PATH`, cujo padrão é `/v1/webhooks/hub`. Exponha essa porta ao Streaming Hub e use o endereço do seu ingress mais esse caminho como URL da assinatura.

O listener de webhook não tem autenticação de aplicação. Ele aceita uma entrega somente quando a assinatura HMAC é válida com o secret da assinatura ou com o secret anterior. Fora de `DEPLOYMENT_MODE=local`, o listener precisa do seu próprio certificado TLS. Como alternativa, termine o TLS na frente dele e defina `EXECUTOR_HUB_WEBHOOK_UPSTREAM_TLS_VALIDATED=true`.

`/readyz` inclui duas verificações do plugin:

* `hub_webhook`: o listener de webhook.
* `executor_institutions`: o número de instituições das quais o plugin é dono e quantas delas têm roteamento do ledger. Esta verificação não reprova a prontidão.

## Restrições de deploy

***

* **Um tenant por processo.** O plugin não inicia quando a sua lista de tenants tem mais de um tenant.
* **O seu próprio banco de dados.** O plugin roda no seu próprio banco PostgreSQL vazio. As suas migrações recusam um banco que já tem outro histórico de migrações.
* **Reinício após mudanças de configuração.** O plugin lê as suas instituições na inicialização.


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