# Separação por Endereço WMS — Spec

## Contexto e problema

A separação de hoje localiza o produto pelo campo legado `produtos.codigo_enderecamento` — um texto livre tipo "1 andar" / "2 andar" que só diz o andar, nunca a posição física. A fila é agrupada por andar via heurística de string e, dentro do andar, ordenada por rota/pedido/nome: nada guia o separador até a prateleira, e a bipagem só confere o código de barras do produto (idêntico em qualquer posição do estoque), sem garantir que ele pegou o item no lugar certo. Enquanto isso, o Genesis já conhece o endereço real de boa parte dos produtos (as missões de Alocação/Operação WMS registram produto × endereço), mas a separação ignora essa base. Sofrem o separador (percurso errático, sem validação de posição) e o gestor (fila sem roteirização física real).

## Escopo

- ✅ Faz parte:
  - Uma variante nova de separação, escolhida **por missão** pelo gestor na Designação, guiada pelo endereço real do produto no WMS local do Genesis.
  - Resolver o endereço real de cada item da missão a partir do registro WMS (última alocação confirmada produto × endereço) e **congelar esse endereço no item na criação** (snapshot), junto do snapshot de códigos de barras que já existe.
  - Fallback legado: item sem endereço WMS registrado cai no comportamento atual (`codigo_enderecamento` / andar), marcado como localização legada; a missão é utilizável mesmo com base WMS parcial.
  - Ordenar/agrupar a fila da variante pela posição física do endereço real, substituindo o agrupamento por andar dentro dessa variante.
  - Execução com validação de endereço: o separador bipa primeiro o endereço; só quando corresponde ao endereço esperado do item a bipagem do produto é liberada.
  - Card exibindo o código real do endereço (ex.: `A03-P2-N1`) com indicação de origem (WMS vs legado).
  - Aviso ao gestor na criação: quantos/quais itens ficaram sem endereço WMS (seguem via fallback), sem bloquear a criação.
  - Registro da validação de endereço na execução (endereço bipado, quando, por quem).
  - Não-regressão total: a separação atual (por andar) permanece intacta e continua sendo o **default**.

- ❌ Fora de escopo:
  - **Não grava movimento de saída nem baixa saldo local WMS.** A variante é só leitura das tabelas WMS (decisão do dono 2026-07-02). Baixa de saldo na separação fica como evolução futura.
  - **Não reserva estoque / anti-oversell** (reafirma decisão de 2026-06-05): separação não reserva nem decrementa estoque; estoque contábil vive no ERP.
  - **Não lê saldo oficial do WMS externo** (não há read API); a fonte é o registro local do Genesis, com o aviso padrão de origem local sempre que saldo for exibido.
  - **Não migra nem remove o `codigo_enderecamento` legado** — continua sendo a fonte da v1 e o fallback da variante.
  - **Não cria gate por empresa** — a escolha é por missão, disponível para todos (decisão do dono 2026-07-02).
  - **Não mexe em carregamento, conferência, pesagem ou nas demais missões** — só a separação ganha a variante.
  - **Não muda a mecânica de bipagem do produto** (snapshot de códigos + fator) nem o claim multi-operador — intocados.
  - **Não gerencia layout de armazém** — o catálogo de endereços é apenas consultado/validado, não editado por esta feature.

## User stories

### US1 — Gestor escolhe a separação por endereço WMS na criação
**Como** gestor logístico **eu quero** escolher, ao criar uma missão de separação, entre o modo atual (por andar) e o modo guiado pelo endereço WMS **para** direcionar o time à posição física real quando a base de endereços cobre a missão.

**Critérios de aceite:**
- AC1.1: No fluxo de criação da missão de separação existe uma opção explícita para o modo "endereço WMS"; o modo atual (por andar) permanece selecionado por **default**.
- AC1.2: A opção aparece para qualquer empresa/usuário — não há gate por empresa.
- AC1.3: A missão criada registra de forma persistente qual modo foi escolhido, e esse modo dirige a fila e a execução do começo ao fim da missão.
- AC1.4: Criar uma missão sem escolher o novo modo produz exatamente a separação de hoje, sem qualquer diferença de comportamento.

### US2 — Endereço real de cada item resolvido e congelado na criação
**Como** gestor logístico **eu quero** que o endereço físico de cada produto da missão seja resolvido e fixado no momento da criação **para** que a fila não pague o custo de reconsultar endereço a cada "próximo item".

**Critérios de aceite:**
- AC2.1: Na criação de uma missão no modo endereço WMS, cada item recebe ou o endereço real resolvido a partir da **última alocação confirmada** do produto no WMS local, ou uma marcação de fallback legado.
- AC2.2: Cada item guarda a **origem** da sua localização: `wms` ou `legado`.
- AC2.3: O endereço/origem fica congelado no item (snapshot) e **não é re-resolvido** a cada pedido de "próximo item".
- AC2.4: Pedir "próximo item" em uma missão no modo endereço WMS **não** adiciona consulta de resolução de endereço por pull em relação ao hot path atual.
- AC2.5: Produto sem endereço WMS registrado recebe origem `legado` e mantém a localização atual (`codigo_enderecamento` / andar).

### US3 — Aviso de cobertura de endereço na criação
**Como** gestor logístico **eu quero** ver, ao montar uma missão por endereço WMS, quantos e quais itens ficaram sem endereço registrado **para** decidir se sigo com fallback parcial ou reforço a base de alocação antes.

**Critérios de aceite:**
- AC3.1: Ao criar a missão no modo endereço WMS, o gestor vê a contagem de itens sem endereço WMS (que seguirão via fallback legado).
- AC3.2: O gestor consegue identificar **quais** itens ficaram sem endereço WMS.
- AC3.3: O aviso é informativo e **não bloqueia** a criação da missão.

### US4 — Fila ordenada pela posição física
**Como** separador em missão por endereço WMS **eu quero** que a fila venha ordenada pelo endereço real de coleta **para** percorrer o armazém na ordem das prateleiras em vez de saltar por andar/rota.

**Critérios de aceite:**
- AC4.1: Na missão por endereço WMS, os itens com origem `wms` são ordenados pela posição física do endereço real.
- AC4.2: Itens em fallback legado entram **no fim** da fila da missão (não intercalados com os itens de endereço WMS).
- AC4.3: A missão de separação **por andar** (default) mantém exatamente a ordenação atual, sem alteração.
- AC4.4: A ordenação da variante é derivada de dado já materializado no item (não recalculada a cada pull), preservando o hot path.

### US5 — Bipagem de endereço antes do produto
**Como** separador em missão por endereço WMS **eu quero** bipar o endereço ao chegar na posição antes de bipar o produto **para** garantir que estou coletando o item no lugar certo.

**Critérios de aceite:**
- AC5.1: No card de um item com origem `wms`, o separador precisa bipar o **endereço** antes de a bipagem do produto ser liberada.
- AC5.2: Quando o endereço bipado corresponde ao endereço esperado do item, a bipagem do produto é liberada e segue com a mecânica atual (snapshot de códigos + fator).
- AC5.3: Quando o endereço bipado é diferente do esperado, o sistema dá feedback de erro e **não** libera a bipagem do produto.
- AC5.4: Só endereços **ativos** no catálogo de endereços são aceitos na validação.
- AC5.5: A distinção entre bip de endereço e bip de produto é feita **por estado do card** (endereço ainda não confirmado → bip é endereço; endereço confirmado → bip é produto), sem depender de formato/prefixo do código.
- AC5.6: Itens em fallback legado **não** exigem bipagem de endereço — vão direto para a bipagem do produto, como hoje.
- AC5.7: A validação de endereço não movimenta saldo nem quantidade — é apenas um gate de localização.
- AC5.8: Cada validação de endereço registra o endereço bipado, quando e por qual operador.
- AC5.9: Com vários operadores na mesma missão, a validação de endereço é por item/operador e não trava o vínculo missão-operador nem a distribuição de itens.

### US6 — Card mostra o endereço real e a origem
**Como** separador **eu quero** ver no card o código do endereço real com indicação de origem **para** saber para onde ir e reconhecer quando o item está em localização legada.

**Critérios de aceite:**
- AC6.1: Para itens com origem `wms`, o card exibe o código real do endereço (ex.: `A03-P2-N1`) no lugar do texto de andar.
- AC6.2: O card indica a origem da localização (endereço WMS vs legado).
- AC6.3: Para itens em fallback legado, o card mostra a localização legada atual, sinalizada como tal.
- AC6.4: Strings novas (badge de endereço, erros de bipagem de endereço, aviso de fallback) aparecem nas 3 línguas suportadas.

### US7 — Escape quando o produto não está no endereço
**Como** separador **eu quero** um caminho claro quando não encontro o produto no endereço esperado **para** não travar a fila nem forçar uma bipagem incorreta.

**Critérios de aceite:**
- AC7.1: Quando o produto não está no endereço esperado, o separador consegue registrar a ocorrência pelo **fluxo de ocorrência da separação já existente** e/ou pular o item.
- AC7.2: O escape não trava a fila para os demais operadores nem quebra o vínculo missão-operador.
- AC7.3: O escape fica registrado no histórico da missão (extrato) de forma auditável.

### US8 — Não-regressão da separação atual
**Como** gestor e separador que usam a separação por andar **eu quero** que ela continue funcionando exatamente como hoje **para** que a variante nova seja puramente aditiva.

**Critérios de aceite:**
- AC8.1: Missões de separação criadas sem o novo modo têm fila, card, ordenação e bipagem idênticos aos atuais.
- AC8.2: A mecânica de bipagem do produto (snapshot de códigos + fator) e o claim multi-operador permanecem inalterados em ambos os modos.
- AC8.3: O campo/valor legado `codigo_enderecamento` continua sendo lido como hoje pela separação por andar.

## Personas envolvidas

| Persona | Papel | Ponto de contato com a feature |
|---|---|---|
| Gestor logístico | Cria a missão de separação na Designação | Escolhe o modo (andar vs endereço WMS); vê o aviso de cobertura de endereço (US1, US3) |
| Separador (operador de armazém) | Executa a separação no app | Fila por posição física; bipa endereço antes do produto; vê o código real no card (US4, US5, US6, US7) |
| Operação de armazém | Mantém a base de alocações WMS viva | Quanto mais alocações confirmadas, maior a cobertura da variante — cria incentivo de manter a base atualizada |
| Tech Lead | Aprova o plano técnico | Decide mecanismo de snapshot, chave da variante, ordenação materializada, registro da validação e integração com a materialização de ordem da fila |

## Dados / entidades-chave (alto nível)

- **Missão de separação** — unidade de trabalho; passa a carregar a marcação de qual modo foi escolhido (por andar vs endereço WMS).
- **Item da missão** — cada produto a coletar; na variante recebe o endereço resolvido (ou marcação de fallback) e a origem (`wms` | `legado`), congelados na criação.
- **Endereço WMS** (`wms_localizacoes`) — catálogo de posições físicas bipáveis (código corredor-prateleira-posição), com estado ativo/inativo; fonte da validação do endereço bipado.
- **Movimento WMS** (`wms_movimentos`) — registro local produto × endereço; a última alocação confirmada é a fonte da resolução de endereço.
- **Snapshot de códigos de barras** — já existente no item; o endereço/origem entra como snapshot irmão.
- **Localização legada** (`produtos.codigo_enderecamento` / andar) — fonte da separação por andar e fallback da variante.
- **Registro de validação de endereço** — endereço bipado, momento e operador, no histórico/execução da missão.

## Regras de negócio

1. O modo de separação (por andar vs endereço WMS) é escolhido **por missão** na criação; o default é a separação atual (por andar).
2. Não há gate por empresa: a opção do modo endereço WMS aparece para todos.
3. Na variante, o endereço de cada item é resolvido na criação a partir da **última alocação confirmada** do produto no WMS local e congelado no item; a fila não re-resolve endereço a cada "próximo item".
4. Item sem endereço WMS registrado recebe origem `legado` e mantém a localização atual (`codigo_enderecamento` / andar); a missão é válida com base WMS parcial (mistura de itens `wms` e `legado`).
5. Na variante, itens com origem `wms` são ordenados pela posição física do endereço; itens `legado` vão para o fim da fila.
6. Na execução da variante, itens com origem `wms` exigem bipagem do endereço **antes** do produto: só quando o endereço bipado corresponde ao esperado a bipagem do produto é liberada; endereço divergente gera feedback de erro e não libera o produto.
7. Itens com origem `legado` não exigem bipagem de endereço.
8. A validação de endereço só aceita endereços **ativos** no catálogo.
9. A validação de endereço é um **gate de localização** — não movimenta saldo nem altera quantidade.
10. A variante é **só leitura** das tabelas WMS: nenhum movimento de saída ou baixa de saldo. Se algum saldo for exibido, carrega o aviso de origem local.
11. A bipagem do produto (snapshot de códigos + fator) e o claim multi-operador (vários operadores na mesma missão) permanecem intocados em ambos os modos.
12. A separação por andar permanece default e sem regressão; a variante é aditiva.
13. Quando o produto não é encontrado no endereço esperado, o separador usa o fluxo de ocorrência já existente e/ou pula o item, sem travar a fila nem o vínculo missão-operador; a ação fica registrada no extrato.
14. Cada validação de endereço na execução é registrada (endereço bipado, quando, por quem).

## Métricas de sucesso

- **Cobertura de endereço**: proporção de itens de missões no modo endereço WMS resolvidos via WMS vs. fallback legado — tende a subir conforme a base de alocação é mantida viva.
- **Adoção**: número/proporção de missões de separação criadas no modo endereço WMS ao longo do tempo.
- **Qualidade de picking**: redução de ocorrências de "produto não encontrado no endereço" e de erros de coleta em missões por endereço WMS comparadas às por andar (proxy de acurácia de posição).
- **Zero regressão da v1**: separação por andar operacional em dev e produção após a entrega, com fila, card e bipagem idênticos.
- **Hot path preservado**: nenhuma consulta adicional por "próximo item" introduzida pela variante em relação ao baseline atual.

## Dúvidas em aberto

> Decisões de produto travadas com o dono em 2026-07-02 (fonte = WMS com fallback legado; execução valida endereço por bipagem; só leitura, sem baixa de saldo; ativação por escolha do gestor por missão, sem gate por empresa). As pendências abaixo cobrem os pontos que o PRD deixou para o PO: as marcadas **(PO — decidido p/ MVP)** já foram fechadas nesta spec; as **(confirmar)** precisam de validação com a operação/dono; as **(TL)** são técnicas e pertencem ao plano técnico.

- [x] **(PO — decidido p/ MVP) Ordem de percurso**: MVP usa ordenação pela sequência do código do endereço + itens legados no fim (AC4.1/AC4.2). **(confirmar)** se existe uma ordem de percurso física (serpentina por corredor) que o código não expressa — se existir, é refinamento pós-MVP.
- [x] **(PO — decidido p/ MVP) Escape de endereço divergente**: o caminho natural é o **fluxo de ocorrência da separação já existente** e/ou pular o item, com registro no extrato (US7). Confirmação forçada com auditoria fica fora do MVP.
- [x] **(PO — decidido p/ MVP) Realocação no meio da missão**: o MVP **aceita a defasagem** do snapshot (endereço congelado na criação); se o produto for realocado durante a missão o card pode apontar para o endereço antigo, e o operador resolve pelo escape (US7). Re-resolução automática ao bipar endereço divergente ou botão "atualizar endereço" ficam como evolução futura.
- [x] **(PO — decidido p/ MVP) Aviso na criação**: listar quantos/quais itens ficaram sem endereço WMS é suficiente para o MVP (US3, informativo e não bloqueante). Ação em massa (ex.: gerar missão de alocação com esses itens) fica como evolução futura.
- [ ] **(confirmar — operação/dono) Interação com a variante por rota**: numa missão por endereço WMS, o percurso físico do endereço vence a prioridade de rota do romaneio (proposta), ou a rota ainda deve preceder o endereço? Precisa de validação da operação antes de fechar o comportamento de ordenação quando as duas dimensões coexistem.
- [ ] **(TL) Materialização e chave da variante**: como marcar a variante sem inflar o catálogo de tipos de missão, e como nascer "materializável" para não colidir com a materialização de ordem da fila (ver `PRD/separacao-fila-throughput/`). O PRD sugere evitar "v2" literal no código.
- [ ] **(TL) Mecanismo do snapshot e do registro da validação**: onde congelar endereço/origem por item e onde registrar o endereço bipado na execução (extrato / dados coletados) — decisão do plano técnico.
