# Separação: throughput da fila (hot path do "próximo item") — Spec

## Contexto e problema

Na separação de itens (`MissaoLogistica`), cada vez que um separador pede o "próximo item" o sistema refaz do zero um trabalho pesado e repetitivo: recalcula a ordem de coleta inteira, consulta o subsistema de romaneios e conta o progresso em três consultas separadas — mesmo quando nada disso mudou desde o pull anterior. Quem sofre é o separador (latência por item) e o gestor (fila lenta para o time). A escala alvo é missão média de ~50 a 500 itens, com **muitos separadores simultâneos na mesma missão** — um cenário normal e suportado (missões em time/`DESIGNADA`), o que multiplica o custo de cada pull.

> **Premissa de domínio (travada pelo dono em 2026-06-05): múltiplos operadores na mesma missão é normal e intencional.** Este trabalho **não** mexe em como operadores entram/saem de uma missão, na contagem de operadores, no claim de fila aberta (`aceitarMissao`/`buscarDisponiveis`) nem na trava já existente que impede dois operadores de pegarem o **mesmo item**. O foco é exclusivamente baratear o custo de produzir cada "próximo item", sem mudar o resultado.

## Escopo

- ✅ Faz parte:
  - Reduzir o trabalho repetido a cada "próximo item", **sem mudar** qual item é entregue nem o progresso exibido.
  - Tornar visível (mensurável) quanto custa cada pedido de "próximo item", para guiar a otimização com números e não no escuro.
  - Para missões cuja ordem de coleta é fixa durante toda a missão, deixar de recalcular essa ordem a cada pull — calcular uma vez e reusar.
  - Manter operacional todo o fluxo do separador (pedir próximo, bipar, concluir, pular, registrar ocorrência), inclusive com vários operadores compartilhando a mesma missão.

- ❌ Fora de escopo:
  - **Qualquer mudança no claim / contagem de operadores por missão.** Múltiplos operadores na mesma missão é normal; não se adiciona trava/índice único no vínculo, não se mexe em `aceitarMissao` nem em `buscarDisponiveis`. (Decisão do dono — "não mexer na fila aberta".)
  - **Reserva de estoque / anti-oversell** (decisão travada pelo dono). A separação não reserva nem decrementa estoque; estoque vive no ERP legado.
  - Mudar a regra de trava na atribuição de **item** individual — já está correta e não muda (é ela que permite o multi-operador sem colisão).
  - Otimizar missões cuja ordem de coleta **varia por operador ou muda no meio da missão** — essas continuam no caminho atual.
  - Otimizar o fluxo de bipagem além de medi-lo — é PRD separado.
  - A colisão de ordenação ao "mover item para o fim da fila" — registrada como dívida, só entra se a medição provar que importa.
  - Migrar o modelo de dados da separação de V1 para V2 — dívida do sinal, fora daqui.

## User stories

### US1 — Próximo item mais rápido, mesmo resultado
**Como** separador **eu quero** que pedir o "próximo item" responda mais rápido **para** processar mais itens por turno sem esperar a cada pick.

**Critérios de aceite:**
- AC1.1: Para a mesma missão no mesmo estado, o item retornado por "próximo item" é **idêntico** ao que era retornado antes da mudança (sequência de itens do começo ao fim da missão inalterada).
- AC1.2: O valor de progresso exibido após cada pick é **idêntico** ao calculado antes da mudança (mesmos totais, concluídos e pendentes).
- AC1.3: O número de consultas ao banco por pedido de "próximo item" cai de forma mensurável em relação ao baseline (alvo numérico definido após a medição da US3).
- AC1.4: O fluxo completo do separador (pedir próximo → bipar → concluir / pular / registrar ocorrência) permanece funcional após a mudança.
- AC1.5: Com vários operadores na mesma missão, nenhum item é entregue a dois operadores ao mesmo tempo (a trava de item existente permanece intacta).

### US2 — Ordem de coleta calculada uma vez
**Como** separador em missão de ordem de coleta fixa (ex.: por rota) **eu quero** que a ordem de coleta seja decidida no início da missão e reusada **para** que cada "próximo item" não pague o custo de recalcular a rota inteira toda vez.

**Critérios de aceite:**
- AC2.1: Para missões com ordem fixa, pedir "próximo item" **não** dispara mais a consulta ao subsistema de romaneios/roteirização a cada pull.
- AC2.2: A sequência de itens entregues do começo ao fim da missão é **idêntica** à atual nessas missões (teste comparando a fila inteira).
- AC2.3: Quando a rota da missão é re-otimizada no meio do caminho, a ordem de coleta reflete a nova rota (a fila não fica defasada com a ordem antiga).
- AC2.4: Missões cuja ordem **varia por operador** ou **muda durante a missão** continuam funcionando exatamente como hoje, sem qualquer alteração de comportamento.
- AC2.5: Existe uma classificação explícita, por tipo de missão, de quais têm ordem fixa (entram nesta otimização) e quais não (permanecem no caminho atual).

### US3 — Saber o custo de cada pull
**Como** dev mantendo a separação **eu quero** enxergar quantas consultas e quanto tempo cada "próximo item" consome **para** decidir o que otimizar com base em dados e comprovar a melhoria depois.

**Critérios de aceite:**
- AC3.1: É possível obter, por pedido de "próximo item", a contagem de consultas ao banco e o tempo total da operação.
- AC3.2: Existe um baseline registrado **antes** das mudanças de throughput (US1/US2), para comparação posterior.
- AC3.3: A coleta dessa medição não degrada perceptivelmente o tempo de resposta do separador em produção.

## Personas envolvidas

| Persona | Papel | Ponto de contato com a feature |
|---|---|---|
| Separador | Operador que coleta itens puxando "próximo item" no app | Sente a latência por pick; ganha throughput direto (US1, US2) |
| Líder / gestor de missão | Acompanha a fila e o time de operadores | Quer a fila andando rápido para o time inteiro; multi-operador multiplica o ganho |
| Dev Genesis | Mantém o sinal `MissaoLogistica` | Precisa de visibilidade do custo do hot path e de um caminho legível (US3) |
| Tech Lead | Aprova o plano técnico e decide a fronteira da US2 | Define mecanismo de medição, onde persistir a ordem fixa e quais missões têm ordem fixa |

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

- **Missão de logística** — a unidade de trabalho; tem um estado (fila aberta, em andamento, concluída) e pode ter **um ou vários** operadores ativos (time).
- **Item da missão** — cada item a ser coletado; tem situação (pendente, em andamento, concluído, pulado) e uma posição na ordem de coleta.
- **Progresso da missão** — totais derivados dos itens (total, concluídos, pendentes ativos), exibidos a cada interação.
- **Ordem de coleta** — a sequência em que os itens devem ser puxados; para algumas missões deriva da rota/roteirização (subsistema de romaneios), para outras varia por operador ou por estado.
- **Extrato da missão** — histórico das ações de separação.

## Regras de negócio

1. O item entregue pelo "próximo item" e o progresso exibido **não podem mudar** em decorrência das otimizações de throughput — só o custo de produzi-los pode cair.
2. A ordem de coleta de uma missão por rota é **constante durante a missão**, exceto quando a rota é explicitamente re-otimizada — nesse caso a ordem deve refletir a nova rota.
3. Missões cuja ordem de coleta depende de qual operador pede o item, ou que muda ao longo da missão, **não** podem ter a ordem fixada antecipadamente — mantêm o cálculo dinâmico.
4. A trava existente que impede dois operadores de pegarem o **mesmo item** permanece intacta — é ela que viabiliza vários operadores na mesma missão.
5. **Múltiplos operadores por missão é normal**; nada neste trabalho restringe ou altera a entrada/contagem de operadores por missão.
6. A separação **não** reserva nem decrementa estoque em nenhum ponto deste trabalho.

## Métricas de sucesso

- Queda mensurável no número de consultas por "próximo item" entre o baseline (US3) e depois das US1/US2, com item entregue e progresso comprovadamente idênticos.
- Para missões de ordem fixa, ausência total de chamadas à roteirização por pull após a US2.
- Zero regressão funcional: separador (pedir → bipar → concluir/pular/ocorrência) operacional em dev e produção após cada entrega, inclusive com vários operadores na mesma missão (distribuição de itens sem colisão).

## Dúvidas em aberto

> As decisões de produto já estão travadas (reserva de estoque fora; claim/fila aberta não se mexe; foco em throughput). As pendências abaixo são **técnicas/de design** e pertencem ao Tech Lead — registradas aqui para não bloquear o planejamento.

- [ ] **(TL)** Onde persistir a ordem de coleta fixada (US2): reusar a posição existente (`ordem`) ou criar um campo dedicado (`ordem_execucao`). Implica decisão de migração e de popular missões já existentes.
- [ ] **(TL)** Qual o gatilho exato de recálculo da ordem quando a rota é re-otimizada no meio da missão (AC2.3) — como o fluxo de edição de rota avisa a fila para não ficar defasada.
- [ ] **(TL + auditoria)** Lista definitiva de quais tipos de missão têm ordem fixa (entram na US2) vs. dependem do operador / mudam durante a missão (ficam de fora). Necessária para fechar o escopo da US2 (AC2.5).
- [ ] **(TL)** A medição da US3 é diagnóstico pontual (temporário) ou instrumentação permanente com amostragem, e onde os dados ficam registrados.
- [ ] **(TL)** Forma de obter o progresso em uma única consulta de leitura respeitando a regra interna de não usar SQL cru para writes (a consulta é leitura agregada — precisa de posição explícita do TL).
- [ ] **(PO/dono)** Confirmar a ordem de entrega recomendada: medir (US3) → quick wins (US1) → ordem fixa (US2) por último.
