# ENG-1473 - Performance da listagem de tarefas de entrada

## Contexto

O card ENG-1473 relata que `/tarefas/entradas` permanece carregando por tempo excessivo no desktop e no mobile. A tela usa `GET /api/v1/stock/picking-order`, servido pelo controller V2.

O fluxo atual combina filtros de tipo/status/setor, suporte a tarefas associadas diretamente a uma entrada e tarefas associadas por produtos, além de relações carregadas para o resource. Durante a serialização, o resource executa consultas individuais para `stock_io` e `all_products_picked`.

## Diagnóstico aprovado

O gargalo provável é composto por:

1. condições repetidas de visibilidade e associação direta/indireta entre o controller e `PickingOrderQueryBuilder`;
2. consultas N+1 executadas durante a serialização de cada tarefa;
3. relações carregadas no índice que não são necessárias para a lista;
4. ausência de uma medição de queries e de um `EXPLAIN (ANALYZE, BUFFERS)` em massa representativa.

O frontend mantém o spinner enquanto a requisição está pendente, mas não é considerado a causa primária.

## Objetivos

- reduzir o tempo de resposta da primeira página de tarefas de entrada;
- impedir que o número de queries cresça linearmente com o número de tarefas retornadas;
- preservar tarefas associadas diretamente e indiretamente;
- preservar filtros de tipo, status, setor, produto e nota fiscal;
- preservar o contrato utilizado pelos detalhes e por tarefas multi-entrada;
- distinguir no frontend carregamento, vazio e erro.

## Abordagem

### Backend

1. Medir a requisição padrão (`type=1`, status pendente/iniciada/pausada) e filtros de produto/NF.
2. Centralizar a visibilidade por setor e a associação direta/indireta no query builder, removendo condições duplicadas do controller sem alterar a semântica.
3. Substituir consultas individuais de `getStockIOReason()` por carregamento em lote ou reutilização das relações carregadas.
4. Calcular `all_products_picked` por `withExists`, subconsulta agregada ou atributo pré-carregado.
5. Manter o contrato do resource; somente separar um resource resumido se os consumidores da rota forem validados previamente.
6. Adicionar índices apenas após confirmar o plano de execução. O índice `integrations (integrable_type, integrable_id)` já existe na migration de índices do dashboard e deve ser verificado no ambiente alvo antes de criar outro.

### Frontend

1. Manter o endpoint e os parâmetros atuais.
2. Adicionar estado explícito de erro, evitando mostrar “Nenhuma tarefa encontrada” quando a API falhar.
3. Cancelar requisições obsoletas quando filtros ou paginação forem alterados, se a medição indicar chamadas concorrentes.

## Testes

- filtros de entrada por produto, nota fiscal e combinação dos dois;
- tarefas diretas e indiretas sem duplicidade;
- visibilidade por setor;
- contrato `stock_io`/`stock_ios` e detalhes;
- contagem de queries que não cresça proporcionalmente ao número de tarefas;
- estado de erro e estado vazio no frontend;
- teste de carga/benchmark e `EXPLAIN (ANALYZE, BUFFERS)` em PostgreSQL representativo.

## Critérios de aceite

- primeira página dentro do limite de latência acordado, com meta inicial de até 2 segundos em ambiente representativo;
- nenhuma consulta individual por tarefa durante a serialização da listagem;
- tarefas, filtros e paginação mantêm o comportamento atual;
- desktop e mobile deixam de permanecer indefinidamente em carregamento;
- nenhuma alteração em dados ou contratos de integração ERP.

## Riscos

- remover uma condição de setor pode ampliar visibilidade; por isso, a cobertura direta/indireta deve ser executada antes e depois da refatoração;
- reduzir relações do índice pode quebrar consumidores externos; o primeiro passo deve preservar o payload;
- índices adicionais podem aumentar custo de escrita; cada índice precisa ser justificado pelo plano de execução.
