# Movimentação WMS — Spec

## Contexto e problema
O WMS já registra *onde* um produto está (operações `alocacao`, `inventario_produtos`, `inventario_endereco`), mas não tem como representar o ato de **transferir** um produto de um endereço para outro. Quando um operador reorganiza um corredor, consolida paletes ou move estoque para a área de expedição, essa movimentação física não tem registro no Genesis e a localização cadastrada passa a divergir da real. Quem sofre é o operador de armazém (sem ferramenta para registrar a transferência no celular), o gestor (perde rastreabilidade) e a integração ERP/WMS (recebe localizações desatualizadas). Esta feature adiciona a `operacao_tipo = movimentacao` ao sinal **AlocacaoWms**, reaproveitando o esqueleto de Operação WMS genérica, com a particularidade de operar sobre **duas localizações** (origem e destino) por movimento.

## Escopo
- ✅ Faz parte:
  - Nova operação `movimentacao` dentro da Missão de Operação WMS (sinal AlocacaoWms), selecionável no mesmo fluxo das demais operações.
  - Execução no app em **sessão livre**: origem, produto, quantidade e destino são todos informados pelo operador, sem nada pré-definido na designação.
  - Fluxo de leitura **Origem → Produto → Quantidade → Destino**.
  - Persistência da movimentação com **origem** e **destino** explícitos no histórico append-only de movimentos (`wms_movimentos`), incluindo as novas localizações de origem e destino.
  - Validação na confirmação específica da movimentação (origem, produto, quantidade e destino presentes; origem diferente de destino; quantidade positiva).
  - Propagação **push** do movimento confirmado para ERP e base WMS, carregando `operacao_tipo = movimentacao` e ambas as localizações, com rastreio de integração por movimento (mesmo mecanismo das operações existentes).
  - Saldo continua sendo de responsabilidade do WMS externo (push-only); Genesis não lê o saldo oficial.
  - Não-regressão das operações já existentes (`alocacao`, `inventario_*`, etc.): a coluna `localizacao_codigo` atual permanece com seu significado para elas.
- ❌ Fora de escopo:
  - **Validação de saldo de origem** (bloquear ou avisar quando a origem não tem estoque suficiente) — o WMS externo reconcilia.
  - **Produto, origem ou destino pré-definidos na designação** (a missão é 100% sessão livre nesta fase).
  - Controle por **lote / validade / série**.
  - **Movimentação em lote orquestrada** (múltiplos produtos em uma missão dirigida por uma lista de itens pré-montada).
  - **Dashboard / relatório de transferências** por período.
  - **Leitura reversa de saldo** do WMS externo (read API).
  - Abate ou ajuste de estoque contábil.

## User stories

### US1 — Gestor cria missão de Movimentação WMS
**Como** gestor de armazém **eu quero** criar uma missão de Operação WMS com a operação "Movimentação" **para** designar a um operador a reorganização/transferência de estoque entre endereços.

**Critérios de aceite:**
- AC1.1: Na criação da Missão de Operação WMS, "Movimentação" aparece como uma das `operacao_tipo` selecionáveis, ao lado das operações já existentes.
- AC1.2: Por ser sessão livre, a criação é aceita **sem nenhum item de escopo** (sem produto, origem ou destino pré-definidos); a missão não é bloqueada por falta de escopo.
- AC1.3: O gestor pode atribuir um ou mais operadores OU deixar a missão disponível para captura por operador habilitado (mesma regra das demais Operações WMS).
- AC1.4: A operação escolhida é persistida em `missao_logistica.configuracoes.operacao_tipo = "movimentacao"`.
- AC1.5: Ao criar, a missão nasce em status "criada/disponível".

### US2 — Operador registra a movimentação no fluxo Origem → Produto → Quantidade → Destino
**Como** operador de armazém **eu quero** bipar o endereço de origem, o produto, informar a quantidade e bipar o endereço de destino **para** registrar que retirei N unidades de um endereço e coloquei em outro.

**Critérios de aceite:**
- AC2.1: A tela de execução lê `operacao_tipo = movimentacao` da missão e renderiza o fluxo de movimentação (campos de origem, produto, quantidade e destino).
- AC2.2: O fluxo segue a ordem Origem → Produto → Quantidade → Destino; bipar o destino é o último gesto antes da confirmação.
- AC2.3: A confirmação só fica habilitada quando origem, produto, quantidade (> 0) e destino estiverem todos preenchidos.
- AC2.4: Ao confirmar, é registrado **um** movimento de `operacao_tipo = movimentacao` contendo origem, produto, quantidade e destino, com status "confirmada".
- AC2.5: Após confirmar, o campo de leitura é reiniciado para registrar a próxima movimentação dentro da mesma sessão, sem perder o histórico já registrado na sessão.
- AC2.6: A origem da leitura de cada código (código de barras ou manual) é registrada no movimento.

### US3 — Operador retoma uma sessão de movimentação em andamento
**Como** operador **eu quero** sair e voltar à missão de movimentação sem perder o que já registrei **para** poder operar de forma intermitente no armazém.

**Critérios de aceite:**
- AC3.1: A execução é livre (sem ordem obrigatória de itens), parcial e retomável; sair e voltar não apaga os movimentos já confirmados na sessão.
- AC3.2: Os movimentos já registrados na sessão ficam visíveis/listados para o operador conferir o que já transferiu.
- AC3.3: A conclusão da missão é **explícita** pelo operador (não há auto-conclusão por contagem de itens, pois é sessão livre — paridade com a alocação).

### US4 — Sistema valida as regras da movimentação na confirmação
**Como** gestor **eu quero** que o sistema valide cada confirmação de movimentação **para** evitar movimentos inconsistentes.

**Critérios de aceite:**
- AC4.1: Confirmação **bloqueada** se a quantidade for nula, zero ou negativa, com mensagem indicando que a quantidade é obrigatória e deve ser positiva.
- AC4.2: Confirmação **bloqueada** se origem e destino forem o mesmo endereço, com mensagem indicando que origem e destino devem ser diferentes.
- AC4.3: Confirmação **bloqueada** se a origem, o produto ou o destino não estiverem informados, com mensagem do campo faltante.
- AC4.4: Se o produto bipado não for encontrado na base de produtos, a leitura é rejeitada com mensagem "produto não encontrado" e a movimentação não avança até que um produto válido seja identificado.
- AC4.5: Confirmação **bloqueada** se a missão não estiver ativa (cancelada/concluída).
- AC4.6: Confirmação **bloqueada** se o operador não tiver permissão para executar a missão.
- AC4.7: Toda confirmação rejeitada exibe o motivo específico e **não** registra nenhum movimento (não grava parcial).

### US5 — Sistema propaga a movimentação (push) para ERP e WMS
**Como** integrador (ERP/WMS externo) **eu quero** receber a movimentação confirmada com origem e destino **para** manter o WMS sincronizado com a transferência física.

**Critérios de aceite:**
- AC5.1: Todo movimento de movimentação confirmado é empurrado para ERP e para a base WMS, carregando `operacao_tipo = movimentacao` no payload.
- AC5.2: O payload carrega **origem** e **destino** de forma explícita (não exige que o consumidor deduza a origem por outra fonte).
- AC5.3: Cada movimento mantém estado de integração ERP e WMS (pendente/enviado/falha) independentes; falha entra em retry e não some silenciosamente.
- AC5.4: O payload ERP usa o identificador compatível com o legado (`importacao_id` ↔ `codigomd5`), como nas demais operações.
- AC5.5: Movimentos cancelados nunca são empurrados (gate por status já existente).
- AC5.6: Quando o WMS externo recusa o movimento por saldo insuficiente na origem, o movimento permanece registrado no Genesis com integração marcada como falha (Genesis **não** bloqueia previamente por saldo nesta fase).

## Personas envolvidas
| Persona | Papel | Ponto de contato com a feature |
|---|---|---|
| Gestor de armazém | Cria a missão de Operação WMS escolhendo "Movimentação" e designa o operador | Tela de criação/Designação |
| Operador de armazém | Executa a movimentação (origem → produto → quantidade → destino) | Aplicativo (sinal `App`) |
| TI / Integração (ERP/WMS externo) | Recebe a movimentação confirmada (push) e reconcilia o saldo | Integração via hook (consumidor) |

## Dados / entidades-chave (alto nível)
- **Missão de Operação WMS (movimentação)** — instância de missão logística genérica com `operacao_tipo = movimentacao` em `configuracoes`.
- **Movimento WMS** — registro append-only do evento de transferência: produto, quantidade, **endereço de origem**, **endereço de destino**, status (confirmada/cancelada), origem da leitura e estados de integração ERP/WMS. A movimentação precisa carregar **duas** localizações (origem e destino), diferente das operações de uma localização só.
- **Produto** — identificado pela leitura (código de barras / manual) e validado contra a base de produtos.
- **Localização WMS (endereço)** — endereço de origem e endereço de destino; apenas referenciados, sem cadastro/gerência de layout aqui.

## Regras de negócio
1. Uma movimentação representa a transferência de N unidades de um produto **de** um endereço de origem **para** um endereço de destino; nunca abate nem movimenta estoque contábil.
2. Cada confirmação gera **um único** movimento de `operacao_tipo = movimentacao`, carregando origem e destino explícitos.
3. A quantidade é **obrigatória** e deve ser **positiva** (> 0); quantidade nula, zero ou negativa rejeita a confirmação.
4. Origem e destino devem ser **endereços diferentes**; origem igual ao destino rejeita a confirmação.
5. Origem, produto, quantidade e destino são **todos obrigatórios** para confirmar.
6. Produto não encontrado na base interrompe o fluxo com mensagem; a movimentação não é confirmada com produto inválido.
7. A missão de movimentação é **sessão livre**: nada é pré-definido na designação (produto, origem e destino são informados pelo operador).
8. **Não há validação de saldo de origem** no Genesis nesta fase; o WMS externo reconcilia e pode recusar via integração (falha + retry).
9. Só missões ativas aceitam novos movimentos; missão cancelada/concluída não aceita.
10. O operador precisa de permissão para executar a missão.
11. Execução sem sequência obrigatória, parcial e retomável; a conclusão é **explícita** pelo operador.
12. A origem da leitura (código de barras / manual) é registrada em cada movimento.
13. Todo movimento confirmado é empurrado (push) para ERP e WMS com origem e destino; movimentos cancelados não são integrados.
14. Integração é push-only nesta fase; nenhuma decisão de execução depende de leitura do saldo oficial do WMS.

## Métricas de sucesso
- Movimentações de `operacao_tipo = movimentacao` sendo efetivamente criadas e confirmadas em produção (a operação saiu do papel).
- % de movimentos de movimentação com integração ERP e WMS confirmada (sem pendência/falha residual).
- Redução de divergência reportada entre localização cadastrada e localização física para os endereços envolvidos em movimentações registradas.
- Zero regressão nas operações WMS já existentes (testes de baseline de alocação/inventário continuam passando).

## Dúvidas em aberto
- [ ] **Semântica da quantidade no push da movimentação**: o consumidor (ERP/WMS) interpreta a quantidade como transferência atômica (debita origem, credita destino) a partir de origem+destino do payload, ou espera dois eventos? *Assunção da spec: um único evento com origem+destino; o WMS aplica como transferência (decisão de payload/contrato fica para o techplan).*
- [ ] **Mesmo produto/origem/destino repetidos na mesma sessão**: registrar movimentos separados (append) ou somar quantidades? *Assunção: append-only, cada confirmação é um movimento independente.*
- [ ] **Feedback ao operador quando o push falha por saldo**: a falha de integração por saldo insuficiente deve gerar alguma sinalização ao operador (notificação/tela) ou fica apenas no rastreio de integração para o gestor? Definir no techplan/UX.
