# Design: Módulo de Regras Genérico

**Data:** 2026-05-18
**Status:** Aprovado

## Problema

O Genesis não possui um lugar centralizado para definir regras de negócio configuráveis por cliente. Regras como "colorir pedido no mapa conforme tempo decorrido" ficam hardcoded nos módulos consumidores, sem possibilidade de o cliente ajustar sem deploy.

## Objetivo

Criar um sistema genérico de regras que:
- Armazena regras por `modulo + regra + acao` com configuração JSON livre
- É consultável por qualquer módulo do Genesis via Laboratório
- Permite ao administrador do cliente configurar regras via UI
- É 100% desacoplado — o módulo Regras não interpreta a `configuracao`, só armazena e entrega

## Modelo de Dados

Tabela `regras`:

```sql
CREATE TABLE regras (
  id              INT AUTO_INCREMENT PRIMARY KEY,
  modulo          VARCHAR(100) NOT NULL,
  regra           VARCHAR(100) NOT NULL,
  acao            VARCHAR(100) NOT NULL,
  configuracao    JSON NOT NULL,
  ativo           TINYINT(1) DEFAULT 1,
  customerControl INT NOT NULL,
  companyControl  INT NOT NULL DEFAULT 0,  -- 0 = todas as filiais (NULL quebraria UNIQUE em MySQL)
  block_created   TINYINT(1),
  block_updated   TINYINT(1),
  block_deleted   TINYINT(1),
  UNIQUE KEY uk_regra (modulo, regra, acao, customerControl, companyControl)
);
```

Exemplos de linhas:

| modulo  | regra                | acao          | configuracao                                         |
|---------|----------------------|---------------|------------------------------------------------------|
| Central | tempo_pedido_no_mapa | alterar_cor   | `{"15":"success","30":"warning","60":"danger"}`      |
| Central | tempo_pedido_no_mapa | enviar_alerta | `{"threshold":60}`                                   |
| Missao  | pedido_sem_movimento | bloquear      | `{"threshold":30}`                                   |

## Estrutura do Sinal

```
componentes/Missoes/Plataforma/sinais/Regras/
  Regras.php
  Sondas/RegraSonda.php
  Laboratorios/ConsultarRegraLaboratorio.php
  Validators/SalvarRegraValidator.php
  Enums/AcaoRegra.php
  Migrations/001_regras_table.sql
  html/regras.php
  html/regras.js
  Testes/Laboratorios/ConsultarRegraLaboratorioTddTest.php
```

API Handlers em `Api/Handlers/Regras/`:

```
ListarHandler.php     # GET    /api/v1/regras?modulo=Central
SalvarHandler.php     # POST   /api/v1/regras
RemoverHandler.php    # DELETE /api/v1/regras/{id}
```

## Registry

`RegrasRegistry` permite que cada módulo declare quais regras ele suporta. A UI lê o Registry para popular os dropdowns de `modulo` e `regra` — sem isso o admin teria que preencher strings manualmente.

```php
// Registrado no boot do controller do módulo consumidor
RegrasRegistry::registrar('Central', 'tempo_pedido_no_mapa', 'Tempo de pedido no mapa');
RegrasRegistry::registrar('Central', 'pedido_sem_cubagem', 'Pedido sem cubagem definida');
```

`AcaoRegra` é uma classe de constantes (não backed enum) — serve apenas como referência de valores conhecidos; o campo `acao` na tabela é VARCHAR livre e aceita qualquer string:

```php
class AcaoRegra {
    const ALTERAR_COR   = 'alterar_cor';
    const ENVIAR_ALERTA = 'enviar_alerta';
    const BLOQUEAR      = 'bloquear';
    const VALOR         = 'valor';
}
```

## Interface de Consumo

```php
// Busca todas as ações configuradas para uma regra
$acoes = (new ConsultarRegraLaboratorio())->consultar(
    modulo: 'Central',
    regra: 'tempo_pedido_no_mapa',
    customerControl: $customerId
);

// Busca uma ação específica
$config = (new ConsultarRegraLaboratorio())->consultarAcao(
    modulo: 'Central',
    regra: 'tempo_pedido_no_mapa',
    acao: 'alterar_cor',
    customerControl: $customerId
);
// $config->configuracao → ["15" => "success", "30" => "warning", "60" => "danger"]
// O módulo Central interpreta e aplica — o Regras não sabe nada de cor
```

`ConsultarRegraLaboratorio` retorna `null` se não houver regra configurada para o cliente. O módulo consumidor define o comportamento padrão nesse caso.

## UI Admin

- Tela lista as regras existentes do cliente agrupadas por módulo
- Formulário: dropdowns para `modulo` e `regra` (populados pelo Registry), campo texto para `acao` (com sugestões do `AcaoRegra` enum), editor JSON para `configuracao`
- Suporte a `companyControl` por filial; 0 = regra global (todas as filiais)
- Toggle `ativo` por regra

## Fluxo de Dados

```
Admin salva regra via UI
  → POST /api/v1/regras (SalvarHandler → SalvarRegraValidator → RegraSonda::create)
  → tabela `regras`

Módulo Central renderiza pedido no mapa
  → ConsultarRegraLaboratorio::consultarAcao('Central', 'tempo_pedido_no_mapa', 'alterar_cor', $customerId)
  → RegraSonda::buscarPorAcao(...)
  → retorna configuracao JSON
  → Central aplica a cor conforme seu próprio critério
```

## Fora do Escopo

- Avaliação automática de limiares (o módulo consumidor avalia o JSON)
- Histórico de alterações de regras
- Herança de regras entre filiais
- Interface para o cliente final (não admin)
