Paginação de grandes volumes de dados
Você é um engenheiro backend especialista em APIs de dados. Me ajude com paginação: o cenário é [DESCREVA: a listagem — o que lista, volume total, ordenação necessária, filtros —, quem consome: frontend com scroll infinito, tabela com páginas numeradas, exportação, outra API], stack [STACK + BANCO], e a dor é [DOR: OFFSET ficando lento nas páginas fundas, itens duplicados/pulados quando a lista muda, precisa de 'ir para página 47', volume travando tudo]. Entregue: a escolha do método com a física explicada (offset/limit — simples e com dois pecados: o banco LÊ e descarta tudo antes do offset — a página 1000 que escaneia 50 mil linhas, e o drift — o item inserido/deletado no meio desloca a janela: duplicado ou pulado no scroll do usuário; cursor/keyset — o padrão certo para volume e scroll infinito: 'me dê os próximos N após ESTE ponto' usando a coluna ordenada — estável e igualmente rápido na página 1 e na 10.000; o veredito para meu caso — e o híbrido honesto quando o produto EXIGE páginas numeradas: offset com limite de profundidade máxima), a implementação do keyset bem feita na minha stack (o cursor sobre coluna única × o desempate obrigatório quando a ordenação tem repetidos — o par (created_at, id) com a comparação de tupla no WHERE: o exemplo SQL/ORM completo; o cursor opaco codificado — base64 do ponteiro, não o ID cru exposto: o cliente não monta cursor na mão; a ordenação descendente e o 'anterior' tratados), o índice que faz tudo funcionar (o índice composto casando EXATAMENTE com o ORDER BY + WHERE — sem ele, keyset vira offset disfarçado: o EXPLAIN conferido), o contrato da API limpo (o formato de resposta: data + next_cursor (null no fim) + has_more — e o limit com teto imposto no servidor: o cliente não pede 100 mil; os filtros que participam do cursor — mudar filtro invalida cursor: o comportamento definido), os casos vizinhos resolvidos (o total count que custa caro — a decisão honesta: exato quando barato, estimado ou omitido quando não; a exportação grande que não é paginação de tela — streaming/job assíncrono; o scroll infinito no frontend consumindo direito — o exemplo), e se eu colar minha query/endpoint atual: a migração de offset para keyset passo a passo com compatibilidade. Objetivo: a página 10.000 tão rápida quanto a primeira — e nenhum item duplicado no scroll do usuário.