PHPackages                             sierratecnologia/operador - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. sierratecnologia/operador

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

sierratecnologia/operador
=========================

Operador para ajudar no desenvolvimento de tasks

0.4.4(2y ago)02013ANCAPPHPPHP ^7.2|^8.0CI failing

Since Jul 29Pushed 6mo agoCompare

[ Source](https://github.com/SierraTecnologia/Operador)[ Packagist](https://packagist.org/packages/sierratecnologia/operador)[ Docs](https://sierratecnologia.com/packages/operador)[ Fund](https://ricasolucoes.com.br/open-source/support-us)[ GitHub Sponsors](https://github.com/ricasolucoes)[ RSS](/packages/sierratecnologia-operador/feed)WikiDiscussions stable Synced 2d ago

READMEChangelogDependencies (2)Versions (19)Used By (3)

Operador!=============
======================

[](#operador)

\[!\[Scrutinizer Code Quality\]([https://scrutinizer-ci.com/g/sierratecnologia/operador/badges/quality-soperador.png?b=master)\](https://scrutinizer-ci.com/g/sierratecnologia/operador/?branch=master)\[!\[Code](https://scrutinizer-ci.com/g/sierratecnologia/operador/badges/quality-soperador.png?b=master)](https://scrutinizer-ci.com/g/sierratecnologia/operador/?branch=master)[![Code) Coverage\]([https://scrutinizer-ci.com/g/sierratecnologia/operador/badges/coverage.png?b=master)\](https://scrutinizer-ci.com/g/sierratecnologia/operador/?branch=master)\[!\[Latest](https://scrutinizer-ci.com/g/sierratecnologia/operador/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/sierratecnologia/operador/?branch=master)[![Latest) Stable Version\]([https://poser.pugx.org/sierratecnologia/operador/v/stable.png)\](https://packagist.org/packages/sierratecnologia/operador](https://poser.pugx.org/sierratecnologia/operador/v/stable.png)](https://packagist.org/packages/sierratecnologia/operador)) \[!\[Total Downloads\]([https://poser.pugx.org/sierratecnologia/operador/downloads.png)\](https://packagist.org/packages/sierratecnologia/operador](https://poser.pugx.org/sierratecnologia/operador/downloads.png)](https://packagist.org/packages/sierratecnologia/operador)) \[!\[Latest Unstable Version\]([https://poser.pugx.org/sierratecnologia/operador/v/unstable.png)\](https://packagist.org/packages/sierratecnologia/operador](https://poser.pugx.org/sierratecnologia/operador/v/unstable.png)](https://packagist.org/packages/sierratecnologia/operador)) \[!\[License\]([https://poser.pugx.org/sierratecnologia/operador/license.png)\](https://packagist.org/packages/sierratecnologia/operador](https://poser.pugx.org/sierratecnologia/operador/license.png)](https://packagist.org/packages/sierratecnologia/operador))

---

Índice
------

[](#índice)

- [Introdução](#introdu%C3%A7%C3%A3o)
- [Instalação](#instala%C3%A7%C3%A3o)
- [Arquitetura e Estrutura Interna](#arquitetura-e-estrutura-interna)
- [Principais Componentes](#principais-componentes)
- [Uso Prático](#uso-pr%C3%A1tico)
- [Integração com o Ecossistema SierraTecnologia](#integra%C3%A7%C3%A3o-com-o-ecossistema-sierratecnologia)
- [Extensão e Customização](#extens%C3%A3o-e-customiza%C3%A7%C3%A3o)
- [Exemplos Reais](#exemplos-reais)
- [Guia de Contribuição](#guia-de-contribui%C3%A7%C3%A3o)
- [Ferramentas de Qualidade](#ferramentas-de-qualidade)

---

Introdução
----------

[](#introdução)

### O que é o Operador?

[](#o-que-é-o-operador)

**Operador** é uma biblioteca Laravel robusta e extensível desenvolvida pela SierraTecnologia para auxiliar no desenvolvimento, orquestração e execução de tarefas automatizadas, actions e processos em batch. A biblioteca oferece uma arquitetura sofisticada baseada em padrões de design consagrados, permitindo a criação de workflows complexos de forma simples e organizada.

### Objetivo e Filosofia do Projeto

[](#objetivo-e-filosofia-do-projeto)

O Operador foi desenvolvido com os seguintes objetivos:

- **Orquestração de Tarefas**: Simplificar a execução de múltiplas ações de forma sequencial ou paralela
- **Modularidade**: Permitir a criação de componentes reutilizáveis e independentes
- **Rastreabilidade**: Oferecer monitoramento detalhado do progresso de execução
- **Extensibilidade**: Facilitar a criação de actions, workers e pipelines customizados
- **Integração**: Integrar-se perfeitamente com o ecossistema Laravel e SierraTecnologia

A filosofia central é proporcionar uma camada de abstração que permita aos desenvolvedores focar na lógica de negócio, enquanto o Operador gerencia a complexidade de orquestração, execução e rastreamento.

### Benefícios de Uso

[](#benefícios-de-uso)

- **Produtividade**: Reduz significativamente o tempo de desenvolvimento de automações complexas
- **Padronização**: Estabelece convenções claras para criação de tarefas e actions
- **Manutenibilidade**: Código organizado e bem estruturado facilita manutenção
- **Reusabilidade**: Componentes podem ser reutilizados em diferentes contextos
- **Rastreamento**: Monitoramento em tempo real do progresso de execução
- **Flexibilidade**: Suporta múltiplos tipos de workers e estratégias de execução

### Ecossistema SierraTecnologia

[](#ecossistema-sierratecnologia)

O Operador se encaixa perfeitamente no ecossistema SierraTecnologia, trabalhando em conjunto com:

- **Muleta**: Traits e contratos utilitários
- **Pedreiro**: Modelos base customizados
- **Tramite**: Sistema de tramitação e workflows
- **Outros pacotes**: Integração transparente com toda a stack SierraTecnologia

---

Instalação
----------

[](#instalação)

### Requisitos Mínimos

[](#requisitos-mínimos)

- **PHP**: ^7.2 ou ^8.0+
- **Laravel**: ^7.0 ou superior
- **Composer**: ^2.0
- **Extensões PHP**: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite

### Instalação via Composer

[](#instalação-via-composer)

Execute o seguinte comando no terminal do seu projeto Laravel:

```
composer require sierratecnologia/operador
```

### Registro Automático do Service Provider

[](#registro-automático-do-service-provider)

O Operador utiliza o auto-discovery do Laravel. O service provider será registrado automaticamente:

```
// Registrado automaticamente via composer.json extra.laravel.providers
Operador\OperadorProvider
```

### Publicação de Configurações (Opcional)

[](#publicação-de-configurações-opcional)

Se necessário, publique as configurações e assets:

```
php artisan vendor:publish --provider="Operador\OperadorProvider"
```

### Executar Migrações

[](#executar-migrações)

Execute as migrações para criar as tabelas necessárias:

```
php artisan migrate
```

As seguintes tabelas serão criadas:

- `bot_runners` - Execução de runners
- `bot_internet_urls` - URLs descobertas
- `bot_internet_url_links` - Relacionamento entre URLs
- `bot_internet_url_forms` - Formulários encontrados
- `bot_internet_url_form_fields` - Campos de formulários
- `references` - Referências dinâmicas
- `referenceables` - Polimorfismo de referências

### Configuração do Ambiente

[](#configuração-do-ambiente)

Se for utilizar integração com Laravel Forge, configure as variáveis de ambiente:

```
FORGE_TOKEN=seu_token_aqui
FORGE_SITE_ID=seu_site_id
FORGE_SERVER_ID=seu_server_id
```

---

Arquitetura e Estrutura Interna
-------------------------------

[](#arquitetura-e-estrutura-interna)

### Estrutura de Diretórios

[](#estrutura-de-diretórios)

```
src/
├── Actions/                  # Actions - padrão principal de execução
│   ├── Action.php           # Classe base de actions
│   ├── ActionCollection.php # Orquestração de múltiplas actions
│   ├── Agir/                # Actions executivas (Excel, Export, Ban/Unban)
│   ├── Collect/             # Actions de coleta (Database, Repository)
│   ├── Instagram/           # Integração com Instagram
│   ├── Hooks/               # Webhooks (NewCommit, etc.)
│   └── Models/              # Actions específicas de modelos
│
├── Components/              # Componentes da aplicação
│   ├── TaskComponent.php    # Base para todas as tasks
│   ├── Processing/          # Processamento de dados
│   ├── Worker/              # Workers especializados
│   │   ├── Explorer/        # Web crawling e scraping
│   │   ├── Logging/         # Processamento de logs
│   │   ├── Deploy/          # Deploy de aplicações
│   │   ├── Sync/            # Sincronização de dados
│   │   ├── Reports/         # Geração de relatórios
│   │   └── Life/            # Health checks
│   ├── View/                # Componentes de visualização
│   ├── Feactures/           # Features avançadas (Assistente, Training)
│   └── Interactions/        # Interações com usuário
│
├── Contracts/               # Interfaces e contratos
│   ├── ActionInterface.php  # Interface de actions
│   ├── RunnerInterface.php  # Interface de runners
│   ├── TaskInterface.php    # Interface de tasks
│   ├── Pipeline.php         # Pipeline base
│   ├── Stage.php            # Stage base
│   └── Attributes/          # Atributos de metadados
│
├── Models/                  # Modelos Eloquent
│   ├── Runner.php           # Executor de actions
│   ├── Task.php             # Tarefa genérica
│   ├── Job.php              # Job da fila
│   └── FailedJob.php        # Jobs que falharam
│
├── Pipelines/               # Pipelines de processamento
│   ├── Pipeline.php         # Pipeline padrão
│   ├── Stages/              # Stages de pipeline
│   └── Handlers/            # Handlers de tipos de dados
│
├── Services/                # Serviços especializados
│   ├── QueueService.php     # Gerenciamento de filas
│   └── ForgeService.php     # Integração com Laravel Forge
│
├── Facades/                 # Laravel Facades
├── Http/Controllers/        # Controllers HTTP
└── OperadorProvider.php     # Service Provider principal

```

### Namespaces

[](#namespaces)

O Operador utiliza PSR-4 autoloading:

```
"autoload": {
    "psr-4": {
        "Operador\\": "src/"
    }
}
```

### Padrões Arquiteturais Adotados

[](#padrões-arquiteturais-adotados)

O Operador emprega diversos padrões de design reconhecidos:

#### 1. **Strategy Pattern**

[](#1-strategy-pattern)

Actions funcionam como estratégias intercambiáveis de processamento. Cada action implementa `ActionInterface` e pode ser executada de forma uniforme.

#### 2. **Pipeline Pattern**

[](#2-pipeline-pattern)

Processamento sequencial de dados através de stages, onde cada stage transforma o payload:

```
Input → Stage1 → Stage2 → Stage3 → Output

```

#### 3. **Builder Pattern**

[](#3-builder-pattern)

Construção fluente de runners e collections:

```
$runner->usingAction($action)->usingTarget($target)->execute();
```

#### 4. **Observer Pattern**

[](#4-observer-pattern)

Board executa callbacks para cada integração/componente, permitindo processamento customizado.

#### 5. **Service Provider Pattern**

[](#5-service-provider-pattern)

Integração com Laravel através de `OperadorProvider`.

#### 6. **Facade Pattern**

[](#6-facade-pattern)

Acesso simplificado a serviços através de facades Laravel.

### Comunicação Entre Camadas

[](#comunicação-entre-camadas)

```
┌─────────────────────────────────────────────────────┐
│                  ActionCollection                    │
│         (Orquestrador principal de actions)         │
└──────────────────┬──────────────────────────────────┘
                   │
                   ├─► Stage 0 (Paralelo)
                   │   ├─► Runner 1 → Action 1 → Worker 1
                   │   ├─► Runner 2 → Action 2 → Worker 2
                   │   └─► Runner 3 → Action 3 → Worker 3
                   │
                   ├─► Stage 1 (Após Stage 0)
                   │   └─► Runner 4 → Action 4 → Worker 4
                   │
                   └─► Stage N
                       └─► Runner N → Action N → Worker N

```

### Convenções e Boas Práticas

[](#convenções-e-boas-práticas)

1. **Nomenclatura**: Classes de actions devem ser verbos no infinitivo (exemplo: `ExportToExcel`, `SearchFollows`)
2. **Responsabilidade Única**: Cada action deve ter uma única responsabilidade bem definida
3. **Imutabilidade**: Pipelines devem retornar novos payloads transformados ao invés de modificar o original
4. **Rastreabilidade**: Sempre utilize `OutputableTrait` para logging consistente
5. **Tipagem**: Utilize type hints e return types em todos os métodos públicos

---

Principais Componentes
----------------------

[](#principais-componentes)

### 1. TaskComponent

[](#1-taskcomponent)

Classe base para todas as tasks e actions do Operador.

**Localização**: `src/Components/TaskComponent.php`

```
use Operador\Components\TaskComponent;

class TaskComponent extends ActionBase
{
    // Tipos de actions disponíveis
    const SPIDER = 1;      // Exploração web
    const ROUTINE = 2;     // Rotinas periódicas
    const HOOK = 3;        // Webhooks/triggers
    const SYNC = 4;        // Sincronização
    const LIFE = 5;        // Health checks

    public $cod;           // Código único da action
    public $classAfetada;  // Classe/modelo afetado
    public $classAExecutar; // Classe executora
    public $type;          // Tipo da action
}
```

**Métodos Principais**:

- `loadActions()`: Carrega todas as actions registradas
- `getActionByCode(string $cod)`: Obtém action por código
- `getModels()`: Lista todos os modelos disponíveis
- `getOnlyActionsForModel($model)`: Filtra actions para um modelo específico

**Exemplo de Uso**:

```
// Obter action por código
$action = TaskComponent::getActionByCode('scanDomain');

// Listar actions para um modelo específico
$actions = TaskComponent::getOnlyActionsForModel(Domain::class);
```

### 2. Action e ActionCollection

[](#2-action-e-actioncollection)

#### Action

[](#action)

Classe base para criar actions executáveis.

**Localização**: `src/Actions/Action.php`

```
use Operador\Actions\Action;

class MinhaAction extends Action
{
    public function execute()
    {
        // Lógica da action
        $this->info('Executando MinhaAction');

        // Processar dados
        $resultado = $this->processar();

        $this->notice('Action executada com sucesso');

        return $resultado;
    }
}
```

#### ActionCollection

[](#actioncollection)

Orquestrador que gerencia múltiplas actions em stages.

**Localização**: `src/Actions/ActionCollection.php`

```
use Operador\Actions\ActionCollection;

$collection = new ActionCollection();

// Adicionar actions ao Stage 0 (executam em paralelo)
$collection->newAction($action1, $stage = 0, $actorNumber = 0);
$collection->newAction($action2, $stage = 0, $actorNumber = 1);

// Adicionar action ao Stage 1 (executa após Stage 0)
$collection->newAction($action3, $stage = 1, $actorNumber = 0);

// Preparar, executar e finalizar
$collection->prepare();
$collection->execute();
$collection->done();

// Monitorar progresso
echo "Progresso: " . $collection->getPorcDone() . "%";
echo "Actions executadas: " . $collection->executedActions;
echo "Total de stages: " . $collection->totalStages();
```

**Principais Métodos**:

- `newAction(ActionInterface $action, int $stage, int $actorNumber)`: Adiciona action
- `newActionCollection(ActionCollection $collection, int $stage)`: Adiciona outra collection
- `prepare()`: Prepara runners para execução
- `execute()`: Executa todos os runners sequencialmente por stage
- `done()`: Finaliza execução
- `run()`: Executa prepare() + execute() + done()
- `getPorcDone()`: Retorna porcentagem de conclusão (0-100)
- `getTotalActionsCount()`: Total de actions
- `getTotalTargetsCount()`: Total de targets

### 3. Runner

[](#3-runner)

Modelo que executa uma action contra um target específico.

**Localização**: `src/Models/Runner.php`

```
use Operador\Models\Runner;

$runner = Runner::makeWithOutput($output);

$runner->usingAction($action)
       ->usingTarget($modelInstance)
       ->prepare()
       ->execute()
       ->done();
```

**Estrutura do Banco de Dados**:

```
Schema::create('bot_runners', function (Blueprint $table) {
    $table->id();
    $table->string('action_code');  // Código da action
    $table->string('target_id');    // ID do target
    $table->string('progress');     // Progresso da execução
    $table->string('task');         // Descrição da task
    $table->string('stage');        // Stage atual
    $table->timestamps();
});
```

### 4. Workers Especializados

[](#4-workers-especializados)

#### Spider - Web Crawler

[](#spider---web-crawler)

Explora sites, extrai links e armazena informações.

**Localização**: `src/Components/Worker/Explorer/Spider.php`

```
use Operador\Components\Worker\Explorer\Spider;

// Criar spider para explorar domínio
$spider = new Spider('https://exemplo.com.br', $follow = true);

// Executar exploração
$spider->execute();
```

**Funcionalidades**:

- Extração automática de links
- Identificação de formulários
- Análise de estrutura do site
- Armazenamento de URLs descobertas
- Suporte a crawling recursivo

#### Logging - Processamento de Logs

[](#logging---processamento-de-logs)

Processa logs de diferentes servidores web.

**Localização**: `src/Components/Worker/Logging/Logging.php`

**Plugins Suportados**:

- Apache
- Nginx
- IIS
- PHP Error Logs

```
use Operador\Components\Worker\Logging\Logging;

$logging = new Logging();
$logs = $logging->findForLogsInServer();
```

#### Deploy Worker

[](#deploy-worker)

Gerencia deploy de aplicações.

**Localização**: `src/Components/Worker/Deploy/DeployBusinessAmbiente.php`

#### Sync Worker

[](#sync-worker)

Sincroniza dados entre sistemas.

**Localização**: `src/Components/Worker/Sync/Project.php`

### 5. Pipeline

[](#5-pipeline)

Sistema de processamento sequencial através de stages.

**Localização**: `src/Pipelines/Pipeline.php`

```
use Operador\Pipelines\PipelineBase;
use Operador\Pipelines\TimesTwoStage;
use Operador\Pipelines\AddOneStage;

$pipeline = (new PipelineBase)
    ->pipe(new TimesTwoStage())     // Multiplica por 2
    ->pipe(new AddOneStage());      // Adiciona 1

$resultado = $pipeline->process(10);  // (10 * 2) + 1 = 21
```

**Criando Stage Customizado**:

```
use Operador\Contracts\Stage;
use Operador\Contracts\StageInterface;

class MeuStage extends Stage implements StageInterface
{
    public function __invoke($payload)
    {
        // Processar payload
        $payloadTransformado = $this->processar($payload);

        // Retornar payload transformado
        return $payloadTransformado;
    }

    private function processar($payload)
    {
        // Lógica de processamento
        return $payload;
    }
}
```

### 6. Board

[](#6-board)

Orquestrador de integrações e componentes.

**Localização**: `src/Components/View/Board.php`

```
use Operador\Components\View\Board;

$board = new Board();

// Executar para cada integração
$board->executeForEachIntegration(function ($integration) {
    $integration->sincronizar();
});

// Executar para cada componente (suporta recursão)
$board->executeForEachComponent(function ($component, $callback) {
    $dados = $integration->obterDados($component);

    foreach ($dados as $item) {
        // Processar subcomponentes recursivamente
        $callback($item);
    }
});
```

**Boards Especializados**:

- `BusinessBoard`: Board de negócios
- `MidiasSocialBoard`: Mídias sociais
- `InfraBoard`: Infraestrutura
- `MarketingBoard`: Marketing
- `PhotoBoard`: Fotos e imagens
- `PersonalBoard`: Tarefas pessoais

### 7. Services

[](#7-services)

#### QueueService

[](#queueservice)

Gerenciamento de filas Laravel.

**Localização**: `src/Services/QueueService.php`

```
use Operador\Services\QueueService;

$queueService = new QueueService();

// Jobs ativos
$active = $queueService->activeJobs();

// Jobs agendados
$upcoming = $queueService->upcomingJobs();

// Jobs que falharam
$failed = $queueService->failedJobs();

// Reiniciar queue
$queueService->restart();

// Retentar todos os jobs
$queueService->retryAll();

// Retentar job específico
$queueService->retry($jobId);

// Cancelar job
$queueService->cancel($jobId, $table);
```

#### ForgeService

[](#forgeservice)

Integração com Laravel Forge.

**Localização**: `src/Services/ForgeService.php`

```
use Operador\Services\ForgeService;

$forgeService = new ForgeService();

// Obter configurações do servidor
$settings = $forgeService->getSettings();

// Gerenciar firewall
$firewalls = $forgeService->getFirewalls();

// Gerenciar sites
$sites = $forgeService->getSites();
$site = $forgeService->getSite($siteId);

// Gerenciar jobs agendados
$jobs = $forgeService->getJobs();
$forgeService->createJob($dados);
$forgeService->deleteJob($jobId);

// Gerenciar workers
$workers = $forgeService->getWorkers();
$forgeService->createWorker($dados);
$forgeService->deleteWorker($workerId);
```

---

Uso Prático
-----------

[](#uso-prático)

### Exemplo 1: Executar Action Simples

[](#exemplo-1-executar-action-simples)

```
use Operador\Components\TaskComponent;
use Operador\Models\Runner;
use Symfony\Component\Console\Output\ConsoleOutput;

// Obter action registrada
$action = TaskComponent::getActionByCode('scanDomain');

// Obter modelo target
$domain = Domain::find(1);

// Criar output para logging
$output = new ConsoleOutput();

// Criar e executar runner
$runner = Runner::makeWithOutput($output)
    ->usingAction($action)
    ->usingTarget($domain)
    ->run();  // prepare() + execute() + done()
```

### Exemplo 2: Executar Múltiplas Actions em Stages

[](#exemplo-2-executar-múltiplas-actions-em-stages)

```
use Operador\Actions\ActionCollection;
use Operador\Components\TaskComponent;

// Criar collection
$collection = new ActionCollection();

// Stage 0: Coletar dados (em paralelo)
$coletarUsuarios = TaskComponent::getActionByCode('coletarUsuarios');
$coletarPosts = TaskComponent::getActionByCode('coletarPosts');

$collection->newAction($coletarUsuarios, 0, 0);
$collection->newAction($coletarPosts, 0, 1);

// Stage 1: Processar dados (após Stage 0)
$processarDados = TaskComponent::getActionByCode('processarDados');
$collection->newAction($processarDados, 1, 0);

// Stage 2: Gerar relatório (após Stage 1)
$gerarRelatorio = TaskComponent::getActionByCode('gerarRelatorio');
$collection->newAction($gerarRelatorio, 2, 0);

// Executar todos os stages sequencialmente
$collection->run();

// Monitorar progresso
echo "Progresso total: " . $collection->getPorcDone() . "%\n";
echo "Actions executadas: {$collection->executedActions} de {$collection->getTotalActionsCount()}\n";
```

### Exemplo 3: Criar Action Customizada

[](#exemplo-3-criar-action-customizada)

```
namespace App\Actions;

use Operador\Actions\Action;
use Operador\Contracts\ActionInterface;

class ExportarRelatorioAction extends Action implements ActionInterface
{
    public function execute()
    {
        $this->info('Iniciando exportação de relatório...');

        try {
            // Obter dados
            $dados = $this->obterDados();

            $this->notice("Coletados {$dados->count()} registros");

            // Processar dados
            $processados = $this->processar($dados);

            // Gerar arquivo
            $arquivo = $this->gerarArquivo($processados);

            $this->info("Relatório gerado: {$arquivo}");

            return [
                'success' => true,
                'file' => $arquivo,
                'records' => $dados->count()
            ];

        } catch (\Exception $e) {
            $this->error("Erro ao exportar relatório: {$e->getMessage()}");

            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }

    private function obterDados()
    {
        return User::with('posts', 'comments')->get();
    }

    private function processar($dados)
    {
        return $dados->map(function ($user) {
            return [
                'nome' => $user->name,
                'email' => $user->email,
                'posts' => $user->posts->count(),
                'comentarios' => $user->comments->count(),
            ];
        });
    }

    private function gerarArquivo($dados)
    {
        $filename = 'relatorio_' . date('Y-m-d_H-i-s') . '.json';
        $path = storage_path("app/reports/{$filename}");

        file_put_contents($path, json_encode($dados, JSON_PRETTY_PRINT));

        return $path;
    }
}
```

**Registrar Action no TaskComponent**:

```
// Em um Service Provider ou no próprio TaskComponent

protected static function getRoutines($actions = [])
{
    $actions[] = self::insertAction(
        'exportarRelatorio',                    // Código único
        \App\Models\User::class,               // Classe afetada
        \App\Actions\ExportarRelatorioAction::class,  // Classe executora
        self::ROUTINE                          // Tipo
    );

    return parent::getRoutines($actions);
}
```

### Exemplo 4: Usar Pipeline

[](#exemplo-4-usar-pipeline)

```
use Operador\Pipelines\PipelineBase;

// Criar stages customizados
class ValidarDadosStage extends Stage
{
    public function __invoke($payload)
    {
        // Validar dados
        if (empty($payload['email'])) {
            throw new \Exception('Email é obrigatório');
        }

        return $payload;
    }
}

class EnriquecerDadosStage extends Stage
{
    public function __invoke($payload)
    {
        // Adicionar informações extras
        $payload['created_at'] = now();
        $payload['ip'] = request()->ip();

        return $payload;
    }
}

class SalvarDadosStage extends Stage
{
    public function __invoke($payload)
    {
        // Salvar no banco
        $user = User::create($payload);

        // Retornar usuário criado
        return $user;
    }
}

// Construir pipeline
$pipeline = (new PipelineBase)
    ->pipe(new ValidarDadosStage())
    ->pipe(new EnriquecerDadosStage())
    ->pipe(new SalvarDadosStage());

// Processar dados
$dados = [
    'name' => 'João Silva',
    'email' => 'joao@exemplo.com'
];

$usuario = $pipeline->process($dados);
```

### Exemplo 5: Spider para Explorar Site

[](#exemplo-5-spider-para-explorar-site)

```
use Operador\Components\Worker\Explorer\Spider;

// Explorar site e extrair todos os links
$spider = new Spider('https://sierratecnologia.com.br', $follow = true);

// Executar exploração
$spider->execute();

// As URLs serão armazenadas automaticamente em:
// - bot_internet_urls (URLs descobertas)
// - bot_internet_url_links (relacionamentos)
// - bot_internet_url_forms (formulários encontrados)
```

### Exemplo 6: Usar Board para Integrações

[](#exemplo-6-usar-board-para-integrações)

```
use Operador\Components\View\Boards\MidiasSocialBoard;

$board = new MidiasSocialBoard();

// Executar rotinas para todas as integrações
$board->executeForEachIntegration(function ($integration) {
    echo "Processando integração: " . get_class($integration) . "\n";

    // Sincronizar dados
    $integration->sincronizar();

    // Coletar novos posts
    $posts = $integration->coletarPosts();

    echo "Coletados {$posts->count()} posts\n";
});

// Processar componentes de forma recursiva
$board->executeForEachComponent(function ($component, $callback) {
    echo "Processando componente: {$component->getName()}\n";

    // Obter dados do componente
    $dados = $component->obterDados();

    // Processar cada item
    foreach ($dados as $item) {
        // Processar subcomponentes recursivamente
        $callback($item);
    }
});
```

### Exemplo 7: Gerenciar Filas com QueueService

[](#exemplo-7-gerenciar-filas-com-queueservice)

```
use Operador\Services\QueueService;

$queueService = new QueueService();

// Listar jobs ativos
$activeJobs = $queueService->activeJobs();

foreach ($activeJobs as $job) {
    echo "Job {$job->id}: {$job->queue} - Tentativas: {$job->attempts}\n";
}

// Listar jobs que falharam
$failedJobs = $queueService->failedJobs();

foreach ($failedJobs as $job) {
    echo "Job falhou: {$job->id} - {$job->exception}\n";
}

// Retentar job específico
if (!empty($failedJobs)) {
    $jobId = $failedJobs[0]->id;
    $queueService->retry($jobId);
    echo "Job {$jobId} reenfileirado\n";
}

// Reiniciar toda a fila
$queueService->restart();
echo "Fila reiniciada\n";
```

---

Integração com o Ecossistema SierraTecnologia
---------------------------------------------

[](#integração-com-o-ecossistema-sierratecnologia)

### Bibliotecas Complementares

[](#bibliotecas-complementares)

O Operador integra-se nativamente com outras bibliotecas da SierraTecnologia:

#### Muleta

[](#muleta)

Fornece traits e contratos utilitários usados pelo Operador:

```
use Muleta\Traits\OutputableTrait;

// Usado em Actions para logging consistente
class MinhaAction extends Action
{
    use OutputableTrait;

    public function execute()
    {
        $this->info('Informação');
        $this->notice('Aviso');
        $this->error('Erro');
    }
}
```

#### Pedreiro

[](#pedreiro)

Modelos base customizados:

```
use Pedreiro\Models\Base;

// Runner e outros models estendem Base
class Runner extends Base
{
    // Herda funcionalidades do Pedreiro
}
```

#### Tramite

[](#tramite)

Sistema de tramitação e workflows:

```
"require": {
    "privatejustice/tramite": "^0.4.0"
}
```

Integração para gerenciamento de fluxos de trabalho complexos.

### Padrões de Versionamento

[](#padrões-de-versionamento)

A SierraTecnologia segue o **Versionamento Semântico** (SemVer):

```
MAJOR.MINOR.PATCH

- MAJOR: Mudanças incompatíveis com versões anteriores
- MINOR: Novas funcionalidades compatíveis
- PATCH: Correções de bugs compatíveis

```

**Exemplo**: `1.2.3`

- `1` = versão major
- `2` = versão minor (novas features)
- `3` = versão patch (bugfixes)

### Testes Automatizados e CI/CD

[](#testes-automatizados-e-cicd)

O Operador utiliza GitHub Actions para CI/CD:

#### Workflows Configurados

[](#workflows-configurados)

1. **Tests** (`.github/workflows/run-tests.yml`)

    - Executa PHPUnit em múltiplas versões de PHP
    - Matrix testing: PHP 7.4, 8.0, 8.1, 8.2
    - Testa em Ubuntu e Windows
2. **PHP CS Fixer** (`.github/workflows/php-cs-fixer.yml`)

    - Verifica e corrige automaticamente code style
    - Padrão PSR-12
    - Auto-commit de correções
3. **Psalm** (`.github/workflows/psalm.yml`)

    - Análise estática de código
    - Nível de erro: 7
    - Detecta bugs potenciais

### Como Diferentes Equipes Podem Aplicar

[](#como-diferentes-equipes-podem-aplicar)

#### Equipe de Backend

[](#equipe-de-backend)

```
// Criar actions para processar dados
class ProcessarPedidosAction extends Action
{
    public function execute()
    {
        $pedidos = Pedido::pendentes()->get();

        foreach ($pedidos as $pedido) {
            $this->processar($pedido);
        }
    }
}
```

#### Equipe de DevOps

[](#equipe-de-devops)

```
// Usar ForgeService para automação
$forgeService = new ForgeService();

// Deploy automático
$forgeService->createJob([
    'command' => 'cd /home/forge/site && git pull origin main',
    'frequency' => 'hourly'
]);
```

#### Equipe de Data

[](#equipe-de-data)

```
// Pipeline de processamento de dados
$pipeline = (new PipelineBase)
    ->pipe(new ExtrairDadosStage())
    ->pipe(new TransformarDadosStage())
    ->pipe(new CarregarDadosStage());

$resultado = $pipeline->process($fonte);
```

#### Equipe de Marketing

[](#equipe-de-marketing)

```
// Board de mídias sociais
$board = new MidiasSocialBoard();

$board->executeForEachIntegration(function ($integration) {
    $integration->publicarPost([
        'titulo' => 'Novidade!',
        'conteudo' => 'Confira nosso novo produto'
    ]);
});
```

---

Extensão e Customização
-----------------------

[](#extensão-e-customização)

### Criar Actions Customizadas

[](#criar-actions-customizadas)

#### Passo 1: Criar Classe da Action

[](#passo-1-criar-classe-da-action)

```
namespace App\Operador\Actions;

use Operador\Actions\Action;
use Operador\Contracts\ActionInterface;

class MinhaActionCustomizada extends Action implements ActionInterface
{
    /**
     * Parâmetros da action
     */
    protected $parametro1;
    protected $parametro2;

    /**
     * Construtor
     */
    public function __construct($parametro1, $parametro2)
    {
        $this->parametro1 = $parametro1;
        $this->parametro2 = $parametro2;
    }

    /**
     * Método principal de execução
     */
    public function execute()
    {
        $this->info('Iniciando MinhaActionCustomizada');

        try {
            // Sua lógica aqui
            $resultado = $this->processar();

            $this->notice('Action executada com sucesso');

            return $resultado;

        } catch (\Exception $e) {
            $this->error("Erro: {$e->getMessage()}");
            throw $e;
        }
    }

    /**
     * Lógica de processamento
     */
    private function processar()
    {
        // Implementar lógica
        return true;
    }
}
```

#### Passo 2: Registrar Action

[](#passo-2-registrar-action)

```
// Em App\Providers\OperadorServiceProvider

use Operador\Components\TaskComponent;

class OperadorServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Estender TaskComponent para registrar action
        TaskComponent::macro('getMinhasActions', function () {
            return [
                TaskComponent::insertAction(
                    'minhaActionCustomizada',           // Código único
                    \App\Models\MeuModelo::class,      // Modelo afetado
                    \App\Operador\Actions\MinhaActionCustomizada::class,  // Classe
                    TaskComponent::ROUTINE             // Tipo
                )
            ];
        });
    }
}
```

#### Passo 3: Usar Action

[](#passo-3-usar-action)

```
use Operador\Components\TaskComponent;
use Operador\Models\Runner;

// Obter action
$action = TaskComponent::getActionByCode('minhaActionCustomizada');

// Executar
$runner = Runner::makeWithOutput($output)
    ->usingAction($action)
    ->usingTarget($modelo)
    ->run();
```

### Criar Workers Customizados

[](#criar-workers-customizados)

```
namespace App\Operador\Workers;

class MeuWorkerCustomizado
{
    /**
     * Output para logging
     */
    protected $output;

    /**
     * Target sendo processado
     */
    protected $target;

    /**
     * Construtor
     */
    public function __construct($output, $target)
    {
        $this->output = $output;
        $this->target = $target;
    }

    /**
     * Executar worker
     */
    public function execute(): bool
    {
        $this->output->writeln('Executando MeuWorkerCustomizado');

        // Sua lógica aqui
        $this->processar();

        $this->output->writeln('Worker executado com sucesso');

        return true;
    }

    /**
     * Processar target
     */
    private function processar()
    {
        // Implementar lógica de processamento
    }
}
```

### Criar Stages de Pipeline Customizados

[](#criar-stages-de-pipeline-customizados)

```
namespace App\Operador\Stages;

use Operador\Contracts\Stage;
use Operador\Contracts\StageInterface;

class MeuStageCustomizado extends Stage implements StageInterface
{
    /**
     * Processar payload
     */
    public function __invoke($payload)
    {
        // Validar payload
        $this->validar($payload);

        // Transformar payload
        $payloadTransformado = $this->transformar($payload);

        // Retornar payload transformado
        return $payloadTransformado;
    }

    /**
     * Validar payload
     */
    private function validar($payload)
    {
        if (!isset($payload['campo_obrigatorio'])) {
            throw new \Exception('Campo obrigatório não encontrado');
        }
    }

    /**
     * Transformar payload
     */
    private function transformar($payload)
    {
        // Adicionar timestamp
        $payload['processed_at'] = now();

        // Adicionar metadados
        $payload['metadata'] = [
            'stage' => 'MeuStageCustomizado',
            'version' => '1.0.0'
        ];

        return $payload;
    }
}
```

**Usar Stage Customizado**:

```
use Operador\Pipelines\PipelineBase;
use App\Operador\Stages\MeuStageCustomizado;

$pipeline = (new PipelineBase)
    ->pipe(new MeuStageCustomizado())
    ->pipe(new OutroStage());

$resultado = $pipeline->process($dados);
```

### Criar Boards Customizados

[](#criar-boards-customizados)

```
namespace App\Operador\Boards;

use Operador\Components\View\Board;

class MeuBoardCustomizado extends Board
{
    /**
     * Definir integrações
     */
    public function getIntegrations(): array
    {
        return array_merge(parent::getIntegrations(), [
            new MinhaIntegracaoCustomizada(),
            new OutraIntegracao(),
        ]);
    }

    /**
     * Definir actions disponíveis
     */
    public function getActions(): array
    {
        return array_merge(parent::getActions(), [
            \App\Actions\MinhaAction::class,
            \App\Actions\OutraAction::class,
        ]);
    }

    /**
     * Definir componentes
     */
    public function getComponents(): array
    {
        return array_merge(parent::getComponents(), [
            'meu_componente' => \App\Components\MeuComponente::class,
        ]);
    }

    /**
     * Executar rotinas customizadas
     */
    public function executeRoutines(): void
    {
        parent::executeRoutines();

        // Suas rotinas customizadas
        $this->minhaRotinaCustomizada();
    }

    /**
     * Rotina customizada
     */
    private function minhaRotinaCustomizada()
    {
        // Implementar lógica
    }
}
```

### Substituir Classes Padrão via IoC

[](#substituir-classes-padrão-via-ioc)

```
// Em App\Providers\AppServiceProvider

public function register()
{
    // Substituir Runner padrão
    $this->app->bind(
        \Operador\Models\Runner::class,
        \App\Operador\Models\MeuRunnerCustomizado::class
    );

    // Substituir ActionCollection
    $this->app->bind(
        \Operador\Actions\ActionCollection::class,
        \App\Operador\Actions\MinhaCollectionCustomizada::class
    );
}
```

### Boas Práticas para Manutenção

[](#boas-práticas-para-manutenção)

1. **Documentação**: Sempre documente suas classes e métodos customizados
2. **Testes**: Escreva testes unitários para actions e workers customizados
3. **Versionamento**: Mantenha compatibilidade com a API do Operador
4. **Logging**: Utilize `OutputableTrait` para logging consistente
5. **Tratamento de Erros**: Sempre capture e trate exceções adequadamente
6. **Code Style**: Siga os padrões PSR-12
7. **Type Hints**: Utilize type hints e return types

---

Exemplos Reais
--------------

[](#exemplos-reais)

### Exemplo 1: Sistema de Processamento de Pedidos

[](#exemplo-1-sistema-de-processamento-de-pedidos)

**Cenário**: E-commerce que precisa processar pedidos automaticamente em múltiplos estágios.

**Solução com Operador**:

```
namespace App\Actions\Pedidos;

use Operador\Actions\ActionCollection;
use Operador\Components\TaskComponent;

class ProcessarPedidosAutomaticamente
{
    public function executar()
    {
        $collection = new ActionCollection();

        // Stage 0: Validar pedidos
        $validarPedidos = TaskComponent::getActionByCode('validarPedidos');
        $collection->newAction($validarPedidos, 0);

        // Stage 1: Processar pagamentos
        $processarPagamentos = TaskComponent::getActionByCode('processarPagamentos');
        $collection->newAction($processarPagamentos, 1);

        // Stage 2: Gerar notas fiscais
        $gerarNotasFiscais = TaskComponent::getActionByCode('gerarNotasFiscais');
        $collection->newAction($gerarNotasFiscais, 2);

        // Stage 3: Enviar para logística
        $enviarLogistica = TaskComponent::getActionByCode('enviarLogistica');
        $collection->newAction($enviarLogistica, 3);

        // Stage 4: Notificar clientes
        $notificarClientes = TaskComponent::getActionByCode('notificarClientes');
        $collection->newAction($notificarClientes, 4);

        // Executar pipeline completo
        $collection->run();

        return [
            'success' => true,
            'progress' => $collection->getPorcDone(),
            'actions_executed' => $collection->executedActions
        ];
    }
}
```

**Resultado**:

- ✅ Processamento automatizado de pedidos
- ✅ Execução sequencial garantida
- ✅ Rastreamento de progresso em tempo real
- ✅ Fácil manutenção e extensão

### Exemplo 2: Sincronização de Dados de Múltiplas APIs

[](#exemplo-2-sincronização-de-dados-de-múltiplas-apis)

**Cenário**: Sistema que precisa sincronizar dados de Instagram, Facebook e Twitter.

**Antes (Sem Operador)**:

```
// Código desorganizado e difícil de manter
class SincronizarMidiasSociais
{
    public function executar()
    {
        // Instagram
        try {
            $instagramApi = new InstagramApi();
            $posts = $instagramApi->getPosts();
            foreach ($posts as $post) {
                Post::updateOrCreate(['instagram_id' => $post->id], $post->toArray());
            }
        } catch (\Exception $e) {
            Log::error("Erro Instagram: " . $e->getMessage());
        }

        // Facebook
        try {
            $facebookApi = new FacebookApi();
            $posts = $facebookApi->getPosts();
            foreach ($posts as $post) {
                Post::updateOrCreate(['facebook_id' => $post->id], $post->toArray());
            }
        } catch (\Exception $e) {
            Log::error("Erro Facebook: " . $e->getMessage());
        }

        // Twitter
        try {
            $twitterApi = new TwitterApi();
            $posts = $twitterApi->getTweets();
            foreach ($posts as $post) {
                Post::updateOrCreate(['twitter_id' => $post->id], $post->toArray());
            }
        } catch (\Exception $e) {
            Log::error("Erro Twitter: " . $e->getMessage());
        }
    }
}
```

**Depois (Com Operador)**:

```
use Operador\Components\View\Boards\MidiasSocialBoard;

class SincronizarMidiasSociais
{
    public function executar()
    {
        $board = new MidiasSocialBoard();

        // Executar sincronização para todas as integrações
        $board->executeForEachIntegration(function ($integration) {
            $this->info("Sincronizando {$integration->getName()}");

            // Coletar posts
            $posts = $integration->coletarPosts();

            // Salvar no banco
            foreach ($posts as $post) {
                Post::updateOrCreate(
                    [$integration->getName() . '_id' => $post->id],
                    $post->toArray()
                );
            }

            $this->notice("Sincronizados {$posts->count()} posts de {$integration->getName()}");
        });
    }
}
```

**Benefícios**:

- ✅ Código 70% mais conciso
- ✅ Fácil adicionar novas integrações
- ✅ Logging consistente
- ✅ Tratamento de erros centralizado
- ✅ Manutenção simplificada

### Exemplo 3: Web Scraping e Análise de Concorrência

[](#exemplo-3-web-scraping-e-análise-de-concorrência)

**Cenário**: Sistema de inteligência de mercado que monitora sites concorrentes.

**Solução com Operador**:

```
use Operador\Components\Worker\Explorer\Spider;
use Operador\Actions\ActionCollection;

class MonitorarConcorrentes
{
    protected $concorrentes = [
        'https://concorrente1.com.br',
        'https://concorrente2.com.br',
        'https://concorrente3.com.br',
    ];

    public function executar()
    {
        $collection = new ActionCollection();

        // Stage 0: Explorar sites (paralelo)
        foreach ($this->concorrentes as $index => $url) {
            $spider = new Spider($url, $follow = true);
            $explorarAction = new ExplorarSiteAction($spider);
            $collection->newAction($explorarAction, 0, $index);
        }

        // Stage 1: Extrair preços
        $extrairPrecos = TaskComponent::getActionByCode('extrairPrecos');
        $collection->newAction($extrairPrecos, 1);

        // Stage 2: Analisar mudanças
        $analisarMudancas = TaskComponent::getActionByCode('analisarMudancas');
        $collection->newAction($analisarMudancas, 2);

        // Stage 3: Gerar alertas
        $gerarAlertas = TaskComponent::getActionByCode('gerarAlertas');
        $collection->newAction($gerarAlertas, 3);

        // Executar
        $collection->run();

        return [
            'sites_explorados' => count($this->concorrentes),
            'progress' => $collection->getPorcDone()
        ];
    }
}
```

**Resultados**:

- ✅ Monitoramento automatizado de concorrentes
- ✅ Exploração paralela de múltiplos sites
- ✅ Detecção automática de mudanças de preços
- ✅ Alertas em tempo real

### Exemplo 4: Pipeline de Processamento de Imagens

[](#exemplo-4-pipeline-de-processamento-de-imagens)

**Cenário**: Sistema de galeria que processa uploads de imagens.

**Solução com Pipeline**:

```
use Operador\Pipelines\PipelineBase;

// Stages customizados
class ValidarImagemStage extends Stage
{
    public function __invoke($payload)
    {
        if ($payload['size'] > 10 * 1024 * 1024) {
            throw new \Exception('Imagem maior que 10MB');
        }

        if (!in_array($payload['mime'], ['image/jpeg', 'image/png'])) {
            throw new \Exception('Formato inválido');
        }

        return $payload;
    }
}

class RedimensionarImagemStage extends Stage
{
    public function __invoke($payload)
    {
        $imagem = Image::make($payload['path']);

        // Criar thumbnails
        $payload['thumbnails'] = [
            'small' => $this->resize($imagem, 150, 150),
            'medium' => $this->resize($imagem, 300, 300),
            'large' => $this->resize($imagem, 800, 800),
        ];

        return $payload;
    }

    private function resize($imagem, $width, $height)
    {
        $filename = uniqid() . '.jpg';
        $path = storage_path("app/thumbnails/{$width}x{$height}/{$filename}");

        $imagem->fit($width, $height)->save($path);

        return $path;
    }
}

class OtimizarImagemStage extends Stage
{
    public function __invoke($payload)
    {
        // Otimizar imagem original
        $optimizer = OptimizerChainFactory::create();
        $optimizer->optimize($payload['path']);

        // Otimizar thumbnails
        foreach ($payload['thumbnails'] as $thumbnail) {
            $optimizer->optimize($thumbnail);
        }

        return $payload;
    }
}

class SalvarBancoDadosStage extends Stage
{
    public function __invoke($payload)
    {
        $imagem = Imagem::create([
            'path' => $payload['path'],
            'thumbnails' => $payload['thumbnails'],
            'size' => $payload['size'],
            'mime' => $payload['mime'],
        ]);

        return $imagem;
    }
}

// Usar pipeline
class ProcessarUploadImagem
{
    public function executar($file)
    {
        $pipeline = (new PipelineBase)
            ->pipe(new ValidarImagemStage())
            ->pipe(new RedimensionarImagemStage())
            ->pipe(new OtimizarImagemStage())
            ->pipe(new SalvarBancoDadosStage());

        $dados = [
            'path' => $file->store('images'),
            'size' => $file->getSize(),
            'mime' => $file->getMimeType(),
        ];

        return $pipeline->process($dados);
    }
}
```

**Benefícios**:

- ✅ Pipeline de processamento claro e organizado
- ✅ Fácil adicionar ou remover etapas
- ✅ Cada stage tem responsabilidade única
- ✅ Facilita testes unitários

---

Guia de Contribuição
--------------------

[](#guia-de-contribuição)

### Como Contribuir

[](#como-contribuir)

Agradecemos seu interesse em contribuir para o Operador! Siga as instruções abaixo:

#### 1. Fork do Repositório

[](#1-fork-do-repositório)

```
# Fork via GitHub
# Depois clone seu fork
git clone https://github.com/seu-usuario/operador.git
cd operador
```

#### 2. Configurar Ambiente Local

[](#2-configurar-ambiente-local)

```
# Instalar dependências
composer install

# Copiar .env.example (se houver)
cp .env.example .env

# Executar migrações
php artisan migrate
```

#### 3. Criar Branch para Feature/Fix

[](#3-criar-branch-para-featurefix)

Siga a convenção de nomenclatura:

```
# Features
git checkout -b feature/nome-da-feature

# Bugfixes
git checkout -b fix/nome-do-bug

# Refatoração
git checkout -b refactor/nome-da-refatoracao

# Documentação
git checkout -b docs/nome-da-documentacao
```

#### 4. Fazer Alterações

[](#4-fazer-alterações)

- Escreva código seguindo PSR-12
- Adicione testes para novas funcionalidades
- Mantenha a cobertura de testes
- Documente métodos públicos

#### 5. Executar Testes e Verificações

[](#5-executar-testes-e-verificações)

```
# Executar testes
./vendor/bin/phpunit

# Verificar code style
./vendor/bin/php-cs-fixer fix --dry-run --diff

# Análise estática
./vendor/bin/psalm

# GrumPHP (se configurado)
./vendor/bin/grumphp run
```

#### 6. Commit das Alterações

[](#6-commit-das-alterações)

Siga o padrão de mensagens de commit:

```
# Formato: tipo(escopo): descrição

# Exemplos:
git commit -m "feat(actions): adicionar suporte a retry em actions"
git commit -m "fix(runner): corrigir memory leak em execução paralela"
git commit -m "docs(readme): atualizar exemplo de pipeline"
git commit -m "test(spider): adicionar testes para Spider::explore"
git commit -m "refactor(collection): simplificar lógica de stages"
```

**Tipos de Commit**:

- `feat`: Nova funcionalidade
- `fix`: Correção de bug
- `docs`: Documentação
- `test`: Testes
- `refactor`: Refatoração
- `style`: Formatação de código
- `perf`: Melhoria de performance
- `chore`: Tarefas gerais

#### 7. Push e Pull Request

[](#7-push-e-pull-request)

```
# Push para seu fork
git push origin feature/nome-da-feature

# Criar Pull Request via GitHub
# Descreva claramente as mudanças
# Referencie issues relacionadas
```

### Padrões de Código

[](#padrões-de-código)

#### PSR-12

[](#psr-12)

O Operador segue rigorosamente o padrão PSR-12:

```
