# Rule Engine Overview

The rule container allows business behaviour to change without a deploy. Rules can be stored in the database (`business_rules`) or loaded from `storage/rules.json`. The loader merges both sources and delivers only the active rules to the application.

## Data model

| Field        | Description                                                                 |
|--------------|-----------------------------------------------------------------------------|
| `id`         | Auto-increment primary key.                                                 |
| `title`      | Friendly label shown in the admin panel.                                    |
| `slug`       | Technical identifier used to fetch a rule (`unique`).                       |
| `description`| Free text with hints for the business team.                                 |
| `category`   | Logical group (examples: `validacao`, `financeiro`, `motor_diario`).        |
| `rule_json`  | JSON payload with parameters/formulas.                                      |
| `is_active`  | Disabled rules stay stored but are ignored by the engine.                   |
| `priority`   | Load order inside the same category (smaller value = higher priority).      |
| `version`    | Manual version tag for auditing.                                            |
| `created_by` / `updated_by` | User responsible for the last change.                        |

JSON rules imported from `storage/rules.json` follow the same schema; any extra keys are ignored.

## Global helper

```php
$engine = rules();

$financeiro = $engine->getRegra('financeiro');
$validacoes = $engine->getTodasRegras('validacao');

if ($financeiro) {
    $payload = $engine->evaluateSimpleExpression($financeiro, [
        '_context' => 'loan.commission',
        'commission_base_amount' => 82000,
        'requested_amount' => 82000,
        'created_at' => '2025-08-10',
    ]);
}
```

Each rule is returned as `App\Services\Rules\RuleDefinition` exposing:

```php
$rule->id;
$rule->title;
$rule->slug;
$rule->category;
$rule->payload;     // decoded JSON array
$rule->priority;
$rule->version;
$rule->origin;      // "database" or "file"
```

## Admin experience

Administrators can manage rules through the **Regras** menu:

1. List, search and filter rules by category.
2. Create/edit rules with validation and JSON preview.
3. Import/export via JSON (textarea or file upload).
4. Toggle the `is_active` flag without deleting the record.

Every CRUD action invalidates the in-memory cache so the new behaviour is applied immediately.

## Categories in use

### `validacao`

Controls dynamic validation for forms (e.g., leads). The structure supports multiple field constraints, custom error messages and execution contexts:

```json
{
  "validations": [
    {
      "contexts": ["lead.store", "lead.update"],
      "fields": ["phone"],
      "constraints": { "required": true, "numeric": true, "min_length": 10, "max_length": 11 },
      "message": "Informe um telefone com DDD (10 ou 11 dígitos)."
    }
  ]
}
```

### `financeiro`

Used by `RuleScheduler` to block operations outside the allowed window (weekdays, business hours, blocked dates) and to enforce amount limits before changing a proposal status.

### `motor_diario`

Drives the daily task generator. Example payload:

```json
{
  "horario_execucao": "07:00",
  "reset_diario": true,
  "tarefas": [
    {
      "tipo": "enviar_orcamento",
      "formula": "(meta_diaria / ticket_medio) / taxa_conversao",
      "descricao": "Enviar {resultado} orçamentos para alcançar R$ {meta_diaria}",
      "arredondar": "cima"
    },
    {
      "tipo": "digitar_contrato",
      "formula": "(meta_diaria / ticket_medio)",
      "descricao": "Digitar pelo menos {resultado} contratos",
      "arredondar": "cima"
    }
  ]
}
```

The daily job reads the rule, resolves the formulas using the indicators for each operator, creates micro tasks for the day, and resets the previous sets.

### Other categories

- `comissao`: applies different commission percentages based on the requested amount (commission base) or date range.
- `financeiro` + `motor_diario` work in tandem with the new daily task engine.

## Logging and error handling

All parsing/validation errors are written to `storage/logs/rules.log`. Invalid rules are skipped without interrupting the application flow.

## Extending the engine

1. Add a new category and payload structure.
2. Consume the rule through the helper in your service/controller.
3. Provide a documentation snippet and, if needed, a quick action in the admin panel.

Guidelines:
- Prefer semantic keys (`"limite_superior": 15000`) to ease auditing.
- Keep formulas simple; the evaluator supports arithmetic operators and numeric variables.
- Use `_context` when calling `evaluateSimpleExpression` so the same rule can serve multiple modules.
