# PRD — Hook Ajuste de Dados: envio explícito de `block` ao ERP

## Problema / dor

Quando o gestor aprova uma missão de **Ajuste de Dados** no Genesis, um webhook (`update_dados_logistica`) é disparado pro ERP legado pra sincronizar `codigo_barras`, `peso_bruto`, `cubagem` e `codigo_enderecamento` do produto. Hoje esse webhook:

1. **Em produção funciona "por sorte"**: o ERP usa o `INDICE_USO` do contexto da requisição (montado a partir da assinatura/cliente no `clientes_trabalhos`) como filtro `block` no UPDATE. Coincide com o block do produto porque é o mesmo cliente.

2. **Em dev silenciosamente falha**: o ERP cai num branch que hardcoda `INDICE_USO = '2'` (Ini.inc.php:199), e como os produtos importados têm `block = 22`, o `UPDATE ... WHERE codigomd5 = :c AND block = INDICE_USO` afeta **zero linhas** — mas retorna `status: ok` porque não houve erro de SQL. Resultado: impossível validar o fluxo no dev, e nenhum sinal de erro nem em prod se algo do contexto quebrar.

3. **Acoplamento implícito**: o Genesis confia que o ERP vai "adivinhar" o tenant certo via subdomínio/sessão. Qualquer mudança no bootstrap do ERP quebra o webhook sem aviso.

A solução proposta é o Genesis **enviar explicitamente o `block`** (tenant id da sessão do gestor que aprovou) no payload, e o ERP **exigir e validar esse `block`** no WHERE — sem depender do `INDICE_USO` ambiente.

## Personas (alto nível)

- **Gestor logístico** — aprova missão de Ajuste de Dados; é dono da ação que dispara o webhook. O `block` enviado vem da sessão dele.
- **Sistema Genesis (servidor)** — chama o webhook via Bearer token; precisa saber o `block` do contexto do gestor.
- **ERP legado** — recebe o webhook, valida o `block` recebido, atualiza o produto com WHERE estrito.
- **Dev/QA** — precisa conseguir validar o fluxo de ponta-a-ponta no ambiente `dev-` sem que `INDICE_USO` hardcoded sabote o teste.

## O que precisa fazer (alto nível)

### 1. ERP — `gerenciar.php` (opc=update_dados_logistica)
- Aceitar novo campo `block` no POST (obrigatório, int > 0).
- Rejeitar requisição com `block` ausente/inválido (mensagem clara).
- Trocar `WHERE codigomd5 = :c` por `WHERE codigomd5 = :c AND block = :b` no `ExeRead` (existência) e no `ExeUpdate`.
- Bypassar o auto-block do `INDICE_USO` (passar `$principal = 'EmpresaSem'` no `ExeRead` e `$tipo = 'EmpresaSem'` no `ExeUpdate`).
- Retornar o `block` no JSON de resposta pra auditoria.

### 2. Genesis — `MissoesAprovacao::sincronizarErpAjusteDados`
- Capturar o `block` do gestor que está aprovando:
  ```php
  $block = getSession('galaxiaUserInfo')->customerData->id ?? null;
  ```
- Validar antes de disparar (sem `block`, abortar com extrato registrado).
- Adicionar `block` em cada item do array `$payloads` enviado pro `AjusteDadosHookStrategy::sincronizar`.
- Incluir `block` no payload registrado no extrato `ERP_HOOK_AJUSTE_DADOS`.

### 3. Validação dev
- Após a alteração, o disparo deve funcionar contra `dev-galpaodasembalagens.goldieapp.com.br` com produtos reais (`block = 22`), retornando "Produto atualizado" e atualizando de fato a coluna no ERP.
- Auditável via extrato (`payloads` já é gravado).

## Fora do escopo

- **Mudar a estratégia base do hook** (`HookSincronizadorBase`): essa mudança é só no `AjusteDadosHookStrategy`. Outras strategies (Falta, Recusa, SeparacaoIniciada, Devolucao) continuam usando o `INDICE_USO` ambiente.
- **Multi-tenant Genesis dinâmico**: a URL do hook continua hardcoded em `galpaodasembalagens` no `__construct` do `HookSincronizadorBase`. Só vira problema quando Genesis servir múltiplas assinaturas.
- **Validar que `block` Genesis sempre bate com `block` ERP**: assumimos que `produtos.block` no Genesis = `1goldie_produtos.block` no ERP (verdade hoje por causa do fluxo de importação). Se um dia divergir, é outro PRD.
- **Substituir o `INDICE_USO` global do ERP**: continua sendo a base do auto-block pra todas as outras operações; só o webhook `update_dados_logistica` deixa de depender dele.
- **Backfill de extratos antigos** (`ERP_HOOK_AJUSTE_DADOS` sem `block`): registros já gravados ficam como estão.

## Restrições / dependências conhecidas

- **Padrão ERP de bypass de block** — `'EmpresaSem'` é o sentinel reconhecido por `Read.class.php` e `Update.class.php` pra não injetar `block = :bl1`. Já existe; vamos usá-lo.
- **Bearer token `gnesistk`** — continua sendo a autenticação do webhook. Sem ele, qualquer um poderia enviar `block` arbitrário e atualizar produto de outro tenant. Manter inalterado.
- **`customerData->id` na sessão Galaxia** — padrão já estabelecido (`MissoesPersistencia.php:334`, `MissoesAgrupamento.php:214`). Default = `1` quando ausente, mas no fluxo de aprovação a sessão sempre está populada (gestor logado).
- **`$tipo = 'EmpresaSem'` no `ExeUpdate`** — bypassa o auto-block; segurança fica por conta do `AND block = :b` explícito no WHERE. Sem o `:b`, abriria atualização cross-tenant — por isso `block` obrigatório no ERP.
- **Snapshot `dados_adicionais.importacao_id`** — já implementado em `GestaoMissoesAjuste`. Pre-requisito desse PRD pra que `codigomd5` correto chegue ao ERP. (Já validado em prod.)
- **Dois ambientes pra testar**: dev (`dev-galpaodasembalagens`) e prod (`galpaodasembalagens`). O fix deve funcionar nos dois — em prod já funcionava; em dev passa a funcionar.

## Métricas de sucesso

- **100% dos disparos `ERP_HOOK_AJUSTE_DADOS` retornam `status: ok` E atualizam de fato a linha no ERP** (validar via SELECT pós-aprovação em dev).
- **Zero updates silenciosos** — toda divergência de `block` resulta em "Produto não encontrado" explícito no log do webhook, não `status: ok` enganoso.
- **Extrato auditável**: campo `block` presente em todos os novos registros `ERP_HOOK_AJUSTE_DADOS`.
- **Dev paridade com prod**: aprovação de missão AJUSTE_DADOS em dev resulta em mudança visível na tabela `1goldie_produtos` do ERP dev.

## Inspirações / referências

- **`MissoesPersistencia::batchInsertItens`** (linha 332-334) — padrão de pegar `block` da sessão.
- **`Update.class.php` linha 81** (`if ($tipo != 'EmpresaSem')`) — sentinel do ERP pra bypassar auto-block.
- **PRD `compras`** — padrão V2, Sondas/Laboratorios/Validators; aqui é mudança cirúrgica (não cria entidade nova), mas serve como referência de formato.

## Dúvidas em aberto pro PO

1. **`block` no payload** deve ser obrigatório (rejeitar requisição sem ele) ou opcional com fallback no `INDICE_USO` (compatibilidade reversa)? Recomendação: obrigatório — fail-loud > silencioso.
2. **Outros hooks do mesmo arquivo** (`FaltaHookStrategy`, `RecusaHookStrategy`, `SeparacaoIniciadaHookStrategy`, `DevolucaoHookStrategy`) sofrem do mesmo problema? Se sim, escopo deveria ser expandido ou virar PRD-pai com vários filhos?
3. **Comportamento quando `block` Genesis ≠ `block` ERP do produto**: hoje resultaria em "Produto não encontrado". É o desejado, ou queremos log/alerta especial pra detectar dessincronização entre os bancos?
4. **Versionamento do payload**: enviar `version: 2` junto pra o ERP saber que o cliente já manda `block`? Útil se um dia tivermos clientes Genesis em versões diferentes apontando pro mesmo ERP.
5. **Backfill / cleanup**: produtos no ERP dev têm `block = 22` mas `INDICE_USO` dev = `'2'`. Devemos corrigir o `INDICE_USO` do dev (ajuste de DB) também, ou só viver com a divergência agora que o webhook passa a ser independente disso?
