# Task 013 — Migrar `EdicaoRota` para usar este módulo

**Depende de:** 010, 011, 012
**Bloqueia:** retirada do sub-pacote `EdicaoRota/Otp/`

## Objetivo

Substituir o OTP embutido no sinal `EdicaoRota` pelo módulo genérico, sem perda de comportamento e sem big-bang.

## Passos

### 1. Criar Evento próprio do EdicaoRota

`componentes/Missoes/Logistica/sinais/EdicaoRota/Eventos/EdicaoRotaOtpEvento.php`:

```php
namespace GalaxiaMissoes\Logistica\sinais\EdicaoRota\Eventos;

use GalaxiaMissoes\Mensageria\sinais\Otp\Eventos\OtpEventoBase;

class EdicaoRotaOtpEvento extends OtpEventoBase {
    public const CONTEXTO = 'edicao_rota';

    public function aoValidar(object $otp, array $extras = []): void {
        // Abre sessão do motorista que hoje vive em App.php do EdicaoRota
        $token = $otp->referencia_externa;
        if (session_status() === PHP_SESSION_NONE) session_start();
        $_SESSION['edicao_rota_' . $token] = ['autorizado_em' => time()];
    }
}
```

### 2. Bootstrap

Em `EdicaoRota/App.php`, adicionar no `bootstrapCallbacks()`:

```php
if (!OtpEventoRegistry::temRegistro(EdicaoRotaOtpEvento::CONTEXTO)) {
    OtpEventoRegistry::registrar(EdicaoRotaOtpEvento::CONTEXTO, EdicaoRotaOtpEvento::class);
}
OtpConfig::registrar(EdicaoRotaOtpEvento::CONTEXTO, [
    'validade_segundos' => 300,
    'max_tentativas'    => 3,
    'tamanho_codigo'    => 6,
    'canal_padrao'      => 'log',   // será 'sms' quando provider real subir
]);
```

### 3. Substituir Laboratórios antigos por chamadas a `OtpSatelite`

#### `EdicaoRota/Laboratorios/GerarOtpLaboratorio.php`
Vira um wrapper:
```php
$resp = (new OtpSatelite($galaxia, 'criar_e_enviar', [
    'contexto'           => 'edicao_rota',
    'referencia_externa' => $token,
    'destinatario'       => $edicao->telefone_motorista,
    'canal'              => 'log',     // OtpConfig pode sobrescrever
    'dados_adicionais'   => ['identificador_motorista' => $edicao->identificador_motorista],
]))->response;
```

#### `EdicaoRota/Laboratorios/ValidarOtpLaboratorio.php`
Vira:
```php
$resp = (new OtpSatelite($galaxia, 'validar', [
    'contexto'           => 'edicao_rota',
    'referencia_externa' => $entrada['token'],
    'codigo'             => $entrada['codigo'],
    'extras'             => ['ip' => ..., 'user_agent' => ...],
]))->response;
// Sucesso → o EdicaoRotaOtpEvento já abriu a sessão. Resposta encaminhada como antes.
```

### 4. Remover sub-pacote OTP do EdicaoRota

Apagar:
- `EdicaoRota/Otp/OtpSenderInterface.php`
- `EdicaoRota/Otp/OtpSenderLog.php`
- `EdicaoRota/Otp/OtpSenderFactory.php`
- `EdicaoRota/Sondas/EdicaoRotaOtpSonda.php`
- `EdicaoRota/Inteligencias/EdicaoRotaOtp.php` (se ainda existir)
- Atualizar `EdicaoRota/Laboratorios/AprovarEdicaoRotaLaboratorioTddTest.php` retirando seções de OtpSenderFactory.

### 5. Migration de drop

`EdicaoRota/Migrations/002_drop_edicoes_rota_otp.sql`:

```sql
DROP TABLE IF EXISTS edicoes_rota_otp;
```

OBS: drop sem migração de dados — OTP é efêmero por design.

### 6. Atualizar testes do EdicaoRota

- Remover `Testes/Laboratorios/ValidarOtpLaboratorioTddTest.php` (já coberto pelo módulo OTP).
- Adicionar `Testes/Eventos/EdicaoRotaOtpEventoTddTest.php` cobrindo `aoValidar` (abertura de sessão).

## Critério de aceite

- Fluxo motorista (acessa link → recebe código no log → digita → status muda para PENDENTE_APROVACAO) funciona end-to-end.
- Os 5 testes anteriores do EdicaoRota seguem passando após mudanças (com ajustes pontuais para os testes de OTP que migraram).
- Nenhuma referência cruzada de `OtpSender*` resta em `EdicaoRota/`.
- Tabela `edicoes_rota_otp` removida.
