# Fixes pós-Fase 3 — infraestrutura de entrada + destrave do provedor real

> Aplicados em 2026-07-02, após o veredito Merge da re-review (`12-review-fase3.md`).
> Escopo: os dois itens que bloqueavam o plug de um WMS real e estavam FORA do
> diff da Fase 3 (um bug pré-existente de infra + um resíduo da Fase 1).

## 1. `WebhookEndpointSonda::findByChannel()` — lookup global (bug #1 do `11-testes-fase3.md`)

**Problema**: a Sonda tinha `customerControl=true`/`companyControl=true`, então o
`find()` injetava filtros de tenant vindos da **sessão PHP ambiente**. Uma
requisição de webhook externa genuína não carrega sessão Genesis — o canal nunca
era encontrado (404 `unknown_channel`) mesmo com HMAC válido. O receiver inteiro
era inalcançável de fora; os testes só passavam porque alinhavam a sessão
ambiente ao tenant do canal antes de cada chamada.

**Fix** (`componentes/Missoes/Plataforma/sinais/Api/Sondas/WebhookEndpointSonda.php`):
`findByChannel()` agora faz `turnOff(['customerControl','companyControl'])` e
filtra `channel + active + block > 0`. Racional: o `channel` é a identidade
pré-auth (único); o tenant autoritativo vem das colunas da própria linha
(consumidas pelo `ReceberOrdemLaboratorio` via fix M1); a autenticidade é
garantida em seguida pelo HMAC contra o secret desta linha. O guard `block > 0`
preserva o soft-delete do `destroy()` (block=0) e exclui linhas com block NULL.
Único call site: `InboundHandler.php:32`. `listarAtivos()` (tela admin)
permanece tenant-scoped.

**Regressão**: GRUPO E do `tests/integration/IntegracaoWms/ReceberOrdemApiTest.php`
reescrito de `expectFixed()` (bug documentado) para guard positivo — com a sessão
ambiente apontando para empresa inexistente (918273645), o POST HMAC-válido em
`wms-7` é aceito (200), a ordem é gravada na empresa **7** (a do canal) e nada
vaza para o tenant da sessão. Docblocks do teste e comentários da Migration 003
atualizados (descreviam o estado pré-fix).

## 2. Guard de stub do `http_wms` removido (resíduo do M2 da Fase 1)

Na Fase 1 o `HttpWmsProvider` era stub e o M2 do `06-review.md` pediu defesa em
profundidade: guard `PROVEDORES_STUB` no `SalvarConfigLaboratorio` + `<option
disabled>` "(Fase 2 — em breve)" na UI. O provedor é real desde a Fase 2, mas o
guard ficou — na prática era impossível selecionar `http_wms` na tela de config.

**Fix**: guard e const removidos de `Config/Laboratorios/SalvarConfigLaboratorio.php`
(o guard de coerência "provedor registrado" permanece); `disabled`/sufixo
removidos de `html/integracaowms.php` e `forms/salvar_integracao_wms_config.php`.
Nenhum teste dependia do guard (verificado por grep antes da remoção).

## 3. README do sinal

Criado `componentes/Missoes/Logistica/sinais/IntegracaoWms/README.md`: visão
geral do fluxo, status por peça, contrato v1 (entrada e saída), **checklist de
provisionamento por empresa** (canal + config + defines + smoke com curl
assinado), receitas (novo tradutor / novo provedor), testes e gotchas.

## Verificação

- `php -l` limpo nos 5 arquivos tocados.
- Suíte completa do sinal (12 TddTest): 337 asserts / 0 fail.
- Integração: `ConfigIntegracaoTest` 47/0 · `Fase2MigrationsTest` 41/0 ·
  `ReceberOrdemApiTest` **61/0 (0 bugs)** — antes destes fixes: 56/1 (1 bug
  documentado). Zero resíduo no banco (cleanup no finally dos próprios testes).

## Pendências restantes antes do 1º WMS real (inalteradas)

1. Tradutores `separacao`/`movimentacao`/`inventario` (receita no README §7).
2. `define('GENESIS_WMS_HTTP_HMAC_SECRET', ...)` com segredo ≠ bearer (deploy/env).
3. Rotacionar o secret do canal dev `wms-7` ao plugar de verdade (UPDATE na linha).
4. Deploy coordenado das migrations pendentes do domínio (`004` rename +
   `007` aprovacao_gestor de `AlocacaoWms`) junto com o código.
