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

# Motor de regras

> Guia para usar o motor de regras do Tracer para construir lógica de validação dinâmica baseada em expressões.

export const GMetadata = ({children}) => <Tooltip headline="Metadados" tip="Informações adicionais em formato chave-valor anexadas a entidades como contas ou transações — como IDs externos, números de referência ou códigos de departamento." cta="Ver glossário" href="/pt/glossary">
    {children}
  </Tooltip>;

export const GCEL = ({children}) => <Tooltip headline="CEL" tip="Common Expression Language — uma linguagem de expressões leve e segura para avaliar condições de forma rápida. O Tracer usa CEL para definir regras de validação de transações." cta="Ver glossário" href="/pt/glossary">
    {children}
  </Tooltip>;

O motor de regras é o que times de risco e fraude usam para mudar como transações são aprovadas ou bloqueadas, sem mexer no código da aplicação. Cada regra é uma pequena expressão que roda em cada transação que o Tracer valida — "bloquear este MCC para este segmento", "enviar tudo acima de R\$ 50 mil para revisão manual", "negar se a conta estiver suspensa".

**O que muda na sua operação:** mudanças em regras sobem por um endpoint de API, não por uma release. Um analista pode publicar uma nova regra de manhã e vê-la avaliando transações reais em segundos. Cada correspondência fica registrada, então uma ligação de cliente reclamando seis meses depois pode ser rastreada até a regra exata que disparou.

**O trade-off honesto:** você tem que pensar em CEL (Common Expression Language) em vez de Go, Python ou Java. A curva é curta — a maioria das regras tem uma linha — mas quem escreve não é mais o time de aplicação. A contrapartida é zero deploy, auditoria completa e quem está mais perto da política é dono dela.

<Tip>
  **Para quem é este guia?** Analistas de risco e fraude que vão escrever regras, devs integrando a chamada de validação, e oficiais de compliance lendo a trilha de auditoria. Os exemplos em CEL ficam técnicos mais para frente, mas o ciclo de vida e a lógica de decisão são úteis para qualquer um avaliando o produto.
</Tip>

O **motor de regras do Tracer** avalia lógica de validação escrita em <GCEL>CEL (Common Expression Language)</GCEL> — uma linguagem de expressões type-safe da Google. As expressões são compiladas na criação da regra e executadas em cada validação de transação; você altera o comportamento atualizando regras via API, sem redeploy de código.

## Por que usar o motor de regras

***

* **Flexibilidade**: Crie e modifique regras sem deploys de código
* **Desempenho**: Expressões compiladas avaliam em menos de 1ms cada
* **Segurança de tipos**: Sintaxe da expressão validada na criação da regra
* **Toda regra ativa roda**: Todas as regras correspondentes são avaliadas, então a trilha de auditoria registra todos os gatilhos, não apenas a categoria vencedora
* **Baseado em escopo**: Aplique regras a segmentos, contas ou tipos de transação específicos

Ao final deste guia, você irá:

* Entender os conceitos do motor de regras e o fluxo de avaliação
* Criar e testar regras baseadas em expressões
* Gerenciar o ciclo de vida das regras (DRAFT, ACTIVE, INACTIVE, DELETED)
* Aplicar melhores práticas para gerenciamento de regras

***

## O que é o motor de regras

***

O motor de regras é o componente do Tracer responsável por avaliar expressões durante a validação de transações. Ele permite que analistas de fraude e gestores de risco configurem lógica de negócios que executa em tempo real - sem necessidade de deploys de código ou suporte de engenharia.

### Como funciona

<Frame caption="Figure 1. Fluxo de avaliação do motor de regras">
  <img src="https://mintcdn.com/lerian-49cb71fc/ZrZBZTM4DWnrahSd/images/pt/d2/how-rules-works.svg?fit=max&auto=format&n=ZrZBZTM4DWnrahSd&q=85&s=5f3bffcb24970752961688c95b75693d" alt="Como o motor de regras avalia as expressões configuradas em relação ao contexto da transação durante a validação e retorna uma decisão" width="1227" height="284" data-path="images/pt/d2/how-rules-works.svg" />
</Frame>

Neste fluxo:

* **Carregar regras** busca todas as regras ativas do cache (ou banco de dados em caso de cache miss)
* **Avaliar expressões** executa todas as expressões CEL contra o contexto da transação
* **Coletar correspondências** reúne todas as regras que corresponderam e determina a decisão

### Padrão de avaliação

Todas as regras ativas são avaliadas contra cada transação. Não há ordenação por prioridade ou avaliação de curto-circuito. Isso garante:

* Trilha de auditoria completa (todas as regras correspondentes são registradas)
* Sem perda de informação (analistas podem ver todos os gatilhos)
* Lógica simples (sem conflitos de prioridade)

**Precedência de decisão** (da mais alta para a mais baixa):

1. **DENY** — qualquer regra `DENY` que corresponder vence imediatamente.
2. **Limite excedido** — se nenhuma regra DENY corresponder, mas algum limite aplicável for excedido, a decisão é DENY (a precedência das regras se aplica primeiro; limites entram apenas quando nenhuma DENY casou).
3. **REVIEW** — se nenhuma regra DENY corresponder e nenhum limite for excedido, qualquer regra `REVIEW` que corresponder vence.
4. **ALLOW** — se apenas regras `ALLOW` corresponderem, a decisão é ALLOW.
5. **Padrão** — se nenhuma regra corresponder, o Tracer retorna o `DEFAULT_DECISION_WHEN_NO_MATCH` configurado (`ALLOW`, a menos que explicitamente definido como `DENY` para implantações fail-closed).

`matchedRuleIds` na resposta contém todas as regras que corresponderam, independente da categoria vencedora, para que consumidores de auditoria vejam todos os gatilhos.

<Info>
  **Por que DENY vence REVIEW e REVIEW vence ALLOW.** A precedência é fixa e não configurável, de propósito: remove a ambiguidade de "qual regra DENY vence?" em runtime e torna a auditoria trivial — a resposta sempre identifica a ação mais estrita que disparou. O custo é que você não consegue escrever "regras ALLOW que sobrescrevem DENYs"; se você precisa desse padrão, a resposta certa é tornar a regra DENY mais específica.
</Info>

<Note>
  O Tracer retorna decisões; ele não bloqueia transações diretamente. Seu sistema recebe a decisão e é responsável por tomar a ação apropriada (ex.: bloquear, permitir ou enfileirar para revisão).
</Note>

***

## Conceitos principais

***

Antes de criar regras, entenda os elementos fundamentais.

### Regras

Uma regra é uma unidade de lógica de negócios composta por:

* **Expressão** - Uma expressão type-safe que avalia para true ou false
* **Ação** - Qual decisão retornar quando a expressão é verdadeira
* **Escopos** - A quais transações a regra se aplica
* **Status** - O estado do ciclo de vida da regra

### Expressões

Expressões são escritas em **CEL (Common Expression Language)**, uma linguagem type-safe que avalia o contexto da transação e retorna um valor booleano (true ou false). CEL fornece validação em tempo de compilação, então erros de sintaxe são detectados quando você cria a regra - não quando as transações estão sendo processadas.

Exemplos de expressões:

```
amount > 10000
```

```
segment.segmentId == "high-risk-segment-uuid" && amount > 5000
```

```
merchant["category"] == "7995"
```

(`merchant.category` é o código MCC ISO 18245 de 4 dígitos — `"7995"` é o MCC para apostas/cassino. Tanto `merchant.category` quanto `merchant["category"]` são aceitos; os exemplos em produção usam a notação com colchetes por convenção. Se precisar casar com um rótulo textual como `"gambling"`, armazene-o em `metadata` e faça o match por lá.)

Expressões têm acesso ao contexto completo da requisição de validação. As variáveis mais usadas estão listadas abaixo. Para o catálogo completo de cada campo aninhado, tipo e caso de borda (formato UUID, valores de enum, comportamento `omitempty`), consulte o [schema ValidationRequest](/pt/openapi/v3-current/tracer.yaml) na referência da API.

| Variável            | Tipo        | Para o que tipicamente serve                                                        |
| ------------------- | ----------- | ----------------------------------------------------------------------------------- |
| `amount`            | number      | Valor decimal convertido para `float64` na avaliação CEL (máx. `±2^53`).            |
| `transactionType`   | string      | Um dos valores `CARD`, `WIRE`, `PIX`, `CRYPTO`.                                     |
| `subType`           | string      | Texto livre (ex.: `"international"`, `"debit"`). String vazia quando não informado. |
| `currency`          | string      | Código ISO 4217 (ex.: `"BRL"`).                                                     |
| `account.status`    | string      | Um dos valores `active`, `suspended`, `closed`.                                     |
| `merchant.category` | string      | Código MCC ISO 18245, 4 dígitos.                                                    |
| `merchant.country`  | string      | ISO 3166-1 alpha-2 (ex.: `"BR"`).                                                   |
| `segment.segmentId` | string UUID | Escopo de segmento da transação.                                                    |
| `metadata.<chave>`  | any         | Campos customizados que sua integração passa no payload da requisição.              |

<Note>
  `segmentId` e `portfolioId` ficam nas variáveis de primeiro nível `segment` e `portfolio`, **não** em `account`. Para filtrar por segmento, use `segment.segmentId == "..."`, não `account.segmentId == "..."`. Os mapas `segment`, `portfolio` e `merchant` só estão presentes quando a requisição os inclui — proteja com `has(segment)` se sua regra precisa rodar mesmo quando a requisição não carrega um.
</Note>

<Note>
  A avaliação de expressões é limitada pelo `CEL_COST_LIMIT` (padrão `10000`). Expressões que excedem esse custo são rejeitadas no momento da ativação com o código de erro `0342` (limite de custo excedido); erros de tipo na expressão aparecem como `0341`.
</Note>

### Exemplos de expressões por caso de uso

Aqui estão exemplos práticos organizados por cenário de negócio:

#### Regras baseadas em valor

```cel theme={null}
// Bloquear transações acima de um limite
amount > 10000

// Bloquear transferências internacionais de alto valor
transactionType == "WIRE" && subType == "international" && amount > 50000

// Revisar transações de criptomoeda de grande valor
transactionType == "CRYPTO" && amount > 5000
```

#### Regras baseadas em comerciante

```cel theme={null}
// Bloquear comerciantes de jogos de azar
merchant.category == "7995"

// Bloquear categorias de comerciantes de alto risco
merchant.category in ["7995", "5967", "5966"]

// Revisar transações de novos países de comerciantes
merchant.country != "BR" && amount > 1000
```

#### Regras baseadas em conta

```cel theme={null}
// Bloquear contas suspensas
account.status == "suspended"

// Revisar transações de contas recém-criadas
metadata.accountAgeDays < 30 && amount > 500

// Bloquear contas encerradas
account.status == "closed"
```

#### Condições combinadas

```cel theme={null}
// Transação de alto valor de segmento de alto risco
segment.segmentId == "high-risk-segment-uuid" && amount > 5000

// PIX internacional acima do limite
transactionType == "PIX" && subType == "international" && amount > 10000

// Transação de cartão de grande valor para comerciante estrangeiro
transactionType == "CARD" && merchant.country != "BR" && amount > 3000
```

#### Usando metadata

```cel theme={null}
// Bloquear transações de dispositivos não confiáveis
metadata.deviceTrust == "untrusted"

// Revisar primeiras compras acima do limite
metadata.isFirstPurchase == true && amount > 1000

// Bloquear transações fora do horário comercial (usando metadata)
metadata.isBusinessHours == false && amount > 5000

// Clientes VIP contornam certas restrições
metadata.customerTier == "vip" && amount < 50000
```

<Note>
  Campos de metadata são fornecidos pela sua integração. Projete seu payload para incluir o contexto que suas regras precisam.
</Note>

### Ações

Ações determinam a decisão quando uma expressão avalia para true:

| Ação     | Descrição                      |
| -------- | ------------------------------ |
| `ALLOW`  | Permitir a transação           |
| `DENY`   | Negar a transação              |
| `REVIEW` | Encaminhar para revisão manual |

### Escopos

Escopos definem a quais transações uma regra se aplica. Uma regra sem `scopes` é **global** e avalia contra qualquer transação. Uma regra com um ou mais objetos de escopo só avalia quando a transação corresponde a pelo menos um deles (semântica OR entre objetos de escopo).

Dentro de um único objeto de escopo, os campos suportados são:

* `segmentId` - Corresponder transações de um segmento específico
* `portfolioId` - Corresponder transações de um portfólio específico
* `accountId` - Corresponder transações de uma conta específica
* `merchantId` - Corresponder transações para um comerciante específico
* `transactionType` - Corresponder tipos de transação específicos (CARD, WIRE, PIX, CRYPTO)
* `subType` - Corresponder subtipos específicos (debit, credit, instant, etc.)

**Semântica de correspondência:**

* **Dentro de um objeto de escopo:** os campos combinam com AND. Um campo não especificado funciona como wildcard (corresponde a qualquer valor). Pelo menos um campo deve estar definido — objetos de escopo vazios (`{}`) são rejeitados com o código de erro `0358`.
* **Entre múltiplos objetos de escopo na mesma regra:** combinam com OR. A regra corresponde se **qualquer** objeto de escopo corresponder à transação.

Por exemplo, uma regra com dois escopos — um filtrando `transactionType: CARD` e outro filtrando `transactionType: PIX` — executa tanto para transações de cartão quanto para PIX. Um único escopo com `segmentId` E `accountId` exige que a transação corresponda ao segmento E à conta.

***

## Ciclo de vida da regra

***

Regras progridem através de um ciclo de vida definido para garantir implantação segura.

<Frame caption="Figura 2. Ciclo de vida e transições do motor de regras">
  <img src="https://mintcdn.com/lerian-49cb71fc/dIivJl2jpQJ0JZcX/images/pt/d2/rules-limits-lifecycle-tracer.svg?fit=max&auto=format&n=dIivJl2jpQJ0JZcX&q=85&s=fed6366294795ce85a67df481a3d5b2e" alt="Ciclo de vida das regras e dos limites no Tracer, com as transições de estado pelas quais uma definição passa da criação até a aplicação ativa" width="531" height="1050" data-path="images/pt/d2/rules-limits-lifecycle-tracer.svg" />
</Frame>

### Estados

| Estado     | Descrição                                                                                                                                                                                            |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DRAFT`    | Não avaliada; expressão pode ser modificada livremente                                                                                                                                               |
| `ACTIVE`   | Avaliada durante validações; expressão é imutável                                                                                                                                                    |
| `INACTIVE` | Não avaliada; preservada para trilha de auditoria; pode ser reativada. A expressão continua imutável neste estado — para editá-la, mova a regra de volta para DRAFT via `POST /v1/rules/{id}/draft`. |
| `DELETED`  | Excluída via soft delete; não retornada nas listagens e não pode ser recuperada via API, mas a linha permanece no banco de dados para trilha de auditoria.                                           |

### Transições

| Transição    | De              | Para     | Descrição                                                     |
| ------------ | --------------- | -------- | ------------------------------------------------------------- |
| `activate`   | DRAFT, INACTIVE | ACTIVE   | Iniciar avaliação (valida expressão)                          |
| `deactivate` | ACTIVE          | INACTIVE | Parar avaliação                                               |
| `draft`      | INACTIVE        | DRAFT    | Reeditar uma regra previamente desativada antes de reativá-la |
| `delete`     | DRAFT, INACTIVE | DELETED  | Remoção permanente (não pode deletar regras ACTIVE)           |

<Note>
  Regras ativas devem ser desativadas antes da exclusão. Isso previne remoção acidental de regras que estão sendo avaliadas.
</Note>

***

## Criar uma regra

***

Crie regras usando `POST /v1/rules`. Regras são criadas com status `DRAFT` por padrão.

Uma regra requer:

* **name**: Um nome único e descritivo
* **expression**: Uma expressão CEL que avalia para true ou false
* **action**: A decisão a retornar quando a expressão corresponder (ALLOW, DENY ou REVIEW)
* **scopes** (opcional): Limita a quais transações a regra se aplica

Para a estrutura completa do payload e detalhes de campos, consulte a [Referência da API](/pt/reference/tracer/create-rule).

***

## Ativar e desativar regras

***

Após criar uma regra, ative-a para iniciar a avaliação. Desative regras para parar a avaliação sem excluí-las.

| Operação  | Endpoint                         | Descrição                                 |
| --------- | -------------------------------- | ----------------------------------------- |
| Ativar    | `POST /v1/rules/{id}/activate`   | Iniciar avaliação desta regra             |
| Desativar | `POST /v1/rules/{id}/deactivate` | Parar avaliação (preserva para auditoria) |

<Note>
  Desativar uma regra a preserva para fins de auditoria. Use exclusão apenas quando quiser remover permanentemente uma regra.
</Note>

***

## Listar e consultar regras

***

Consulte regras para gerenciamento e auditoria usando `GET /v1/rules`.

### Parâmetros de consulta

| Parâmetro          | Tipo    | Descrição                                                                                       |
| ------------------ | ------- | ----------------------------------------------------------------------------------------------- |
| `name`             | string  | Filtrar por nome (correspondência parcial, case-insensitive)                                    |
| `status`           | string  | Filtrar por status (DRAFT, ACTIVE, INACTIVE). `DELETED` não é um valor válido para este filtro. |
| `action`           | string  | Filtrar por ação (ALLOW, DENY, REVIEW)                                                          |
| `account_id`       | UUID    | Filtrar por escopo: ID da conta                                                                 |
| `segment_id`       | UUID    | Filtrar por escopo: ID do segmento                                                              |
| `portfolio_id`     | UUID    | Filtrar por escopo: ID do portfólio                                                             |
| `merchant_id`      | UUID    | Filtrar por escopo: ID do comerciante                                                           |
| `transaction_type` | string  | Filtrar por escopo: tipo de transação (CARD, WIRE, PIX, CRYPTO)                                 |
| `sub_type`         | string  | Filtrar por escopo: subtipo (ex.: debit, credit)                                                |
| `limit`            | integer | Itens por página (padrão: 10, máx: 100)                                                         |
| `cursor`           | string  | Cursor de paginação da resposta anterior                                                        |
| `sort_by`          | string  | Campo de ordenação: `created_at`, `updated_at`, `name`, `status` (padrão: `created_at`)         |
| `sort_order`       | string  | Direção: `ASC`, `DESC` (padrão: `DESC`)                                                         |

### Obter uma regra específica

Use `GET /v1/rules/{id}` para recuperar a definição completa da regra incluindo expressão e escopos.

***

## Atualizar uma regra

***

Atualize regras usando `PATCH /v1/rules/{id}`. Regras podem ser atualizadas em qualquer status, com uma restrição importante:

<Warning>
  O campo `expression` é imutável nos estados **ACTIVE** e **INACTIVE** — desativar a regra não basta. Para editar uma expressão, mova a regra de ACTIVE → INACTIVE (`POST /v1/rules/{id}/deactivate`) e depois de INACTIVE → DRAFT (`POST /v1/rules/{id}/draft`). Apenas regras DRAFT aceitam alterações na expressão. Após editar, reative com `POST /v1/rules/{id}/activate`.
</Warning>

***

## Excluir uma regra

***

Exclua regras que não são mais necessárias. Apenas regras DRAFT e INACTIVE podem ser excluídas. Regras ACTIVE devem ser desativadas primeiro.

```http theme={null}
DELETE /v1/rules/{id}
X-API-Key: {api_key}
```

Resposta: `204 No Content`

<Warning>
  A exclusão é permanente. Regras excluídas não podem ser recuperadas e não aparecem em nenhuma listagem.
</Warning>

***

## Melhores práticas

***

Siga estas práticas para regras eficazes e manuteníveis.

### Nomenclatura

* **Use nomes descritivos** - O nome deve indicar claramente o que a regra faz
* **Inclua contexto** - Mencione o cenário ou tipo de transação
* **Evite abreviações** - Prefira clareza à brevidade

| Menos claro     | Mais claro                                            |
| --------------- | ----------------------------------------------------- |
| `Regra 1`       | `Bloquear transações noturnas acima de R$ 5.000`      |
| `Bloquear alto` | `Negar transações de alto valor no fim de semana`     |
| `Regra PIX`     | `Revisar transferências PIX para novos destinatários` |

### Design de expressões

* **Mantenha expressões simples** - Lógica complexa é mais difícil de manter
* **Use escopos para filtrar** - Não repita condições de escopo nas expressões
* **Teste casos limite** - Considere valores de fronteira e campos nulos

### Gerenciamento de ciclo de vida

* **Comece em DRAFT** - Teste antes de ativar
* **Volte para DRAFT antes de editar a expressão** - A expressão é imutável em ACTIVE e INACTIVE; mova a regra para DRAFT via `POST /v1/rules/{id}/draft` para editar, depois reative
* **Arquive regras não utilizadas** - Mantenha a trilha de auditoria intacta
* **Exclua apenas quando tiver certeza** - A exclusão é permanente

### Monitoramento

* **Revise regras correspondentes** - Verifique quais regras estão sendo acionadas
* **Monitore taxas de DENY** - Taxas de negação altas podem indicar regras muito agressivas
* **Audite regularmente** - Garanta que as regras ainda estão alinhadas com os requisitos de negócio

<Warning>
  **Tropeços comuns ao trabalhar com regras:**

  * **"Editei a expressão mas a mudança não fez efeito."** A expressão é imutável nos estados ACTIVE e INACTIVE. Mova a regra de volta para DRAFT via `POST /v1/rules/{id}/draft`, edite e reative. INACTIVE sozinho não basta.
  * **"Minha regra está ACTIVE mas o Tracer ainda não está avaliando ela."** O cache de regras atualiza a cada \~10 segundos (`RULE_SYNC_POLL_INTERVAL_SECONDS`). Regras recém-ativadas levam até essa janela para começar a rodar. Planeje testes de integração com esse delay.
  * **"Quero deletar uma regra ACTIVE."** Você não pode — `POST /v1/rules/{id}/deactivate` primeiro, depois `DELETE /v1/rules/{id}`. Isso força um passo visível em que a regra para de afetar o tráfego antes de sumir das listagens.
  * **"Meu escopo vazio `{}` está sendo rejeitado com o código de erro `0358`."** Todo objeto de escopo precisa ter pelo menos um campo definido. Para rodar uma regra globalmente (contra qualquer transação), omita o array `scopes` inteiro — não passe `{}`.
</Warning>

***

## Referência rápida

***

Endpoints, ações e informações de status-chave.

### Endpoints

| Operação             | Método | Endpoint                    |
| -------------------- | ------ | --------------------------- |
| Criar regra          | POST   | `/v1/rules`                 |
| Listar regras        | GET    | `/v1/rules`                 |
| Obter regra          | GET    | `/v1/rules/{id}`            |
| Atualizar regra      | PATCH  | `/v1/rules/{id}`            |
| Excluir regra        | DELETE | `/v1/rules/{id}`            |
| Ativar regra         | POST   | `/v1/rules/{id}/activate`   |
| Desativar regra      | POST   | `/v1/rules/{id}/deactivate` |
| Voltar para rascunho | POST   | `/v1/rules/{id}/draft`      |

### Status

| Status     | Avaliada | Editável                                                    | Pode excluir             |
| ---------- | -------- | ----------------------------------------------------------- | ------------------------ |
| `DRAFT`    | Não      | Sim                                                         | Sim                      |
| `ACTIVE`   | Sim      | Parcial (`expression` imutável)                             | Não (desativar primeiro) |
| `INACTIVE` | Não      | Parcial (`expression` imutável; voltar para DRAFT primeiro) | Sim                      |
| `DELETED`  | Não      | Não                                                         | N/A                      |
