Pular para conteúdo

0032 — Envio em lote por .zip

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-10 · Decidido em: 2026-07-06

Contexto

Até a v2.0.x, o envio era POST /api/transporte/processar com um .xlsx por chamada. O ciclo da Vantroba gera várias planilhas de uma vez: eram N chamadas, cada arquivo com a sua notificação, sem noção de "este ciclo terminou". O bi-comercial-xls já recebia em lote por zip, e os processadores XLS da frota deviam falar o mesmo contrato.

Decisão

  • POST /api/xls/processar, multipart/form-data, campo único arquivo: um .zip com 1..N .xlsx. O zip é o lote. O cliente não manda período — ele vem da aba 10 de cada planilha (0016).
  • O servidor gera o id do lote: conjuntoId = "zip-" + os 60 primeiros hex do SHA-256 do zip (cabe no VARCHAR(64); o mesmo zip gera o mesmo id). Cada .xlsx válido vira um xls_processamento próprio, com checksum próprio, carimbado com o conjunto_id.
  • Migration V16 (conjunto_lote_e_zip): tabela xls_conjunto_lote (conjunto_id PK, total, duplicados, nao_processados, criado_em, notificado_em) e coluna conjunto_id, com índice, em xls_processamento.
  • Resposta 202 = recibo do lote: conjuntoId, total e itens[] com o httpStatus por arquivo (202 enfileirado, 200 já processado, 409 em andamento, 400 não aceito) — a idempotência por checksum continua valendo por arquivo. 400 no nível do lote: zip inválido, vazio ou sem .xlsx.
  • O lote fecha quando todas as entradas terminam — contando as duplicatas já processadas e as entradas não processadas (tipo/magic inválido ou já em andamento) — e então sai um resumo único no Telegram (notificado_em).

Consequências

  • Quebra de contrato (v2.1.0): endpoint e payload mudaram, e as integrações com o endpoint antigo tiveram de migrar (o @OpenAPIDefinition foi a 2.0.0 na v2.1.1). Contrato narrado em dev/api-rest.
  • data_referencia/hora_referencia em xls_processamento viraram legado (não populadas).
  • Arquivos do mesmo lote processam em paralelo — concorrência na mescla, que expôs o deadlock 40P01 resolvido em 0031.
  • Continua sem tela de upload: o envio é só por API.

Alternativas consideradas

  • Manter o .xlsx avulso (status quo): N chamadas e N notificações por ciclo, sem fechamento de lote, e contrato divergente do bi-comercial-xls. Descartado.