# Design: Observação do Operador para o Motorista (EdicaoRota)

**Data:** 2026-05-26
**Feature:** Operador deixa uma observação ao liberar a rota; motorista a vê como card na tela de edição.

---

## Contexto

O modal "Liberar rota para motorista" (`Central/html/central.php`) já tem um ícone de bloco de notas na header. Atualmente ele é inerte. O operador precisa poder escrever uma observação (até 500 chars) que o motorista verá ao abrir a tela de edição da rota.

---

## 1. Banco de dados

**Arquivo:** `Migrations/005_observacao_operador.sql`

```sql
ALTER TABLE edicoes_rota
  ADD COLUMN observacao_operador VARCHAR(500) NULL;
```

- Nullable: observação é opcional.
- Sem `DEFAULT`: valor ausente = NULL, campo não exibido ao motorista.
- Sem `block_*`: não é dado de customer/company control; pertence à própria edição.

---

## 2. Sub-modal do operador (HTML + CSS)

**Arquivo:** `Central/html/central.php`

### 2a. Ícone de bloco de notas no header do modal de liberação

Adicionar botão ao header do `#liberar-motorista-modal`:

```html
<button id="liberar-motorista-obs-btn"
        class="g-liberar-modal-obs-btn"
        type="button"
        title="Adicionar observação para o motorista"
        aria-label="Observação para o motorista">
    <i class="fas fa-sticky-note"></i>
</button>
```

Quando há texto salvo: classe `com-obs` muda a cor do ícone (âmbar) para feedback visual.

### 2b. Sub-modal `#liberar-obs-modal`

Inserido no DOM após `#liberar-motorista-modal`. Estrutura:

- `position: fixed; inset: 0; z-index: 60` (acima do modal pai que é z-50)
- Card com título "Observação para o motorista", `textarea` (max 500), contador regressivo, botões "Cancelar" e "Salvar"
- Ao abrir: preenche o `textarea` com o texto já salvo (se houver)
- Ao clicar "Salvar": guarda texto em variável JS `liberarMotoristaObservacao`, fecha sub-modal, atualiza classe do ícone
- Ao clicar "Cancelar": fecha sem alterar

---

## 3. Estado JS e payload da API

**Arquivo:** `Central/html/central.php` (bloco JS)

### 3a. Variável de estado

```js
let liberarMotoristaObservacao = '';
```

Declarada junto com `liberarMotoristaIti` e `enviadoExibirTela` (linha ~4543).

Resetada no fechamento do modal de liberação (se o modal fechar via Cancelar/X, observação limpa).

### 3b. Incluir no body da criação

No handler do `#liberar-motorista-confirmar` (linha ~5158), após montar `body`:

```js
if (liberarMotoristaObservacao.trim()) {
    body.observacao_operador = liberarMotoristaObservacao.trim();
}
```

### 3c. Reenvio

O reenvio (branch `enviadoExibirTela`, linha ~5051) não recria o registro — chama só `/otp/gerar`. A observação já está salva na criação e persiste. Nenhuma mudança nesse branch.

---

## 4. Backend

### 4a. Validator — `CriarEdicaoRotaValidator.php`

Validação opcional: se `observacao_operador` vier no payload, trim e verificar `strlen <= 500`. Retorna erro se exceder.

### 4b. Laboratório — `CriarEdicaoRotaLaboratorio.php`

No bloco que monta `$payload` (linha ~77), adicionar:

```php
$obsOp = isset($entrada['observacao_operador'])
    ? mb_substr(trim((string) $entrada['observacao_operador']), 0, 500)
    : null;

if ($obsOp !== null && $obsOp !== '') {
    $payload['observacao_operador'] = $obsOp;
}
```

O `EdicaoRotaSonda::make()` repassa ao `ModelInteligencia::save()` sem alteração — basta que a coluna exista.

### 4c. Sonda — `EdicaoRotaSonda.php`

Sem alteração. `ModelInteligencia` lê automaticamente as colunas da tabela. O campo `observacao_operador` estará disponível em `$edicao->observacao_operador` após a migration.

### 4d. Controller — `Edicaorota.php`

No método `telaMotorista()`, onde monta o array para `renderMotorista('html/editar_rota', ...)` (linha ~293), adicionar:

```php
'observacao_operador' => isset($edicao->observacao_operador)
    ? (string) $edicao->observacao_operador
    : null,
```

---

## 5. View do motorista — `html/editar_rota.php`

### 5a. Variável PHP no topo

```php
$observacaoOperador = !empty($observacao_operador) ? (string) $observacao_operador : null;
```

### 5b. Card entre "Planejamento da Rota" e "Sequência de entrega"

Inserido entre as linhas 181 (`</div> <!-- fecha resumo-rota-card -->`) e 183 (`<div class="card"> <!-- Sequência de entrega -->`):

```php
<?php if ($observacaoOperador !== null): ?>
<div class="card obs-operador-card">
  <div class="card-secao-label">
    <i class="card-secao-icone" aria-hidden="true">📝</i>
    <span class="card-secao-texto">Observação do operador</span>
  </div>
  <p class="obs-operador-texto"><?= nl2br(htmlspecialchars($observacaoOperador)) ?></p>
</div>
<?php endif; ?>
```

### 5c. CSS (inline no `_layout.php` ou no próprio `editar_rota.php`)

```css
.obs-operador-card {
  border-color: rgba(251, 191, 36, 0.35);  /* âmbar — distingue do card genérico */
}
.obs-operador-texto {
  margin: 0;
  color: var(--text);
  font-size: 0.95rem;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}
```

---

## Fluxo completo

```
Operador abre modal "Liberar rota"
  → clica ícone bloco de notas
    → sub-modal abre (pré-preenchido se já havia texto)
    → escreve observação (max 500 chars)
    → clica "Salvar" → texto em memória JS, sub-modal fecha, ícone âmbar
  → preenche telefone/canal/tempo
  → clica "Enviar para o motorista"
    → POST /api/v1/edicao-rota com observacao_operador no body
    → CriarEdicaoRotaLaboratorio salva em edicoes_rota.observacao_operador

Motorista abre link
  → ValidarOtp → telaMotorista() → renderMotorista('html/editar_rota', [..., 'observacao_operador' => ...])
  → editar_rota.php renderiza card "Observação do operador" entre Planejamento da Rota e Sequência de entrega
```

---

## Arquivos impactados

| Arquivo | Tipo de mudança |
|---|---|
| `Migrations/005_observacao_operador.sql` | **Novo** |
| `Validators/CriarEdicaoRotaValidator.php` | Editar — validação opcional |
| `Laboratorios/CriarEdicaoRotaLaboratorio.php` | Editar — salvar campo |
| `Edicaorota.php` | Editar — passar var pra view |
| `html/editar_rota.php` | Editar — card observação |
| `Central/html/central.php` | Editar — sub-modal HTML/CSS/JS |

---

## Fora do escopo

- O motorista não pode editar a observação.
- Não há histórico de revisões da observação.
- Observação não aparece no painel de aprovação do gestor (`edicaorota.php`).
- O reenvio não recria o registro; a observação persiste da criação original.
