diff --git a/docs/changelog/2026-09-28-upload-gravacoes-teto-cloudflare.md b/docs/changelog/2026-09-28-upload-gravacoes-teto-cloudflare.md index 9206449a..88354d60 100644 --- a/docs/changelog/2026-09-28-upload-gravacoes-teto-cloudflare.md +++ b/docs/changelog/2026-09-28-upload-gravacoes-teto-cloudflare.md @@ -1 +1 @@ -**Upload de gravações fatiado em 16 MiB escapa do teto de ~100 MB do Cloudflare (2026-09-28):** subir o `.mp4` de 6 GB de uma plenária no acervo de comunicação falhava porque o diálogo enviava o arquivo inteiro em um único XHR e o edge do Cloudflare respondia `413` antes do app ver o corpo — a recusa foi comprovada em produção por um probe read-only de 150 MB (corte após ~3,2 MB), não apurada na suíte, que nunca atravessa o edge. O upload agora é fatiado ponta a ponta com `RECORDING_UPLOAD_CHUNK_BYTES = 16 MiB` e `RECORDING_UPLOAD_EDGE_LIMIT_BYTES = 100 MiB`: o `POST .../gravacoes/enviar` vira start bodyless que devolve o `chunkSize` e abre a sessão em disco, `POST/DELETE .../gravacoes/enviar/[id]` recebem a parte crua por `?index=` e abortam de forma idempotente, e o diálogo fatia por `file.slice` com progresso agregado, aborto por `DELETE` com `keepalive` em erro/unmount e o reaper/`deleteRecordingForActor` limpando o dir da sessão. O start faz preflight de disco (`statfs(tmpdir())` com margem de 512 MiB) para não morrer de ENOSPC após horas, o `413` vira copy honesta no diálogo, e um unit pina `chunk < edge limit` (todo o resto acima de ~100 MB — inclusive a Central de Conteúdos — segue documentado como prevenção cara). Testes int do protocolo (multi-parte, fora de ordem, tamanho excedido, falha S3, reaper, rotas idempotentes) e guardas e2e das rotas verdes, `pnpm gate:fast`/`build`/`knip`/`cycles`/`format` verdes, sem migration e sem schema; PR #— aberto neste worktree, CI e confirmação em produção pendentes. +**Upload de gravações fatiado em 16 MiB escapa do teto de ~100 MB do Cloudflare (2026-09-28):** subir o `.mp4` de 6 GB de uma plenária no acervo de comunicação falhava porque o diálogo enviava o arquivo inteiro em um único XHR e o edge do Cloudflare respondia `413` antes do app ver o corpo — a recusa foi comprovada em produção por um probe read-only de 150 MB (corte após ~3,2 MB), não apurada na suíte, que nunca atravessa o edge. O upload agora é fatiado ponta a ponta com `RECORDING_UPLOAD_CHUNK_BYTES = 16 MiB` e `RECORDING_UPLOAD_EDGE_LIMIT_BYTES = 100 MiB`: o `POST .../gravacoes/enviar` vira start bodyless que devolve o `chunkSize` e abre a sessão em disco, `POST/DELETE .../gravacoes/enviar/[id]` recebem a parte crua por `?index=` e abortam de forma idempotente, e o diálogo fatia por `file.slice` com progresso agregado, aborto por `DELETE` com `keepalive` em erro/unmount e o reaper/`deleteRecordingForActor` limpando o dir da sessão. O start faz preflight de disco (`statfs(tmpdir())` com margem de 512 MiB) para não morrer de ENOSPC após horas, o `413` vira copy honesta no diálogo, e um unit pina `chunk < edge limit` (todo o resto acima de ~100 MB — inclusive a Central de Conteúdos — segue documentado como prevenção cara). Testes int do protocolo (multi-parte, fora de ordem, tamanho excedido, falha S3, reaper, rotas idempotentes) e guardas e2e das rotas verdes, `pnpm gate:fast`/`build`/`knip`/`cycles`/`format` verdes, sem migration e sem schema; PR #1382 aberto, CI e confirmação em produção pendentes. diff --git a/docs/postmortems/2026-09-28-upload-gravacoes-teto-cloudflare.md b/docs/postmortems/2026-09-28-upload-gravacoes-teto-cloudflare.md index 53ddd411..7ee6d56d 100644 --- a/docs/postmortems/2026-09-28-upload-gravacoes-teto-cloudflare.md +++ b/docs/postmortems/2026-09-28-upload-gravacoes-teto-cloudflare.md @@ -10,7 +10,7 @@ | Severidade | alta (bloqueia subir gravações reais de horas no acervo de comunicação em produção) | | Ambiente | produção (sintoma e diagnóstico read-only) + worktree `fix/14` (correção e verificação) | | Issue(s) | sem Issue (relato humano direto no `/bug-fix`) | -| PR do fix | #— (aberto neste worktree) | +| PR do fix | #1382 | | Detectado por | humano (operador da campanha) | ## Timeline @@ -20,7 +20,7 @@ | Início provável | 2026-09-18 | O C199 (gravações enviadas no acervo, commit d0f606a5) entrou com upload de arquivo inteiro em um único request; qualquer upload acima de ~100 MB já era recusado pelo edge do Cloudflare. O C199-large (remoção do teto de 4 GiB, commit 57b0d168, deploy verde em 2026-09-26 17:40) não mudou isso. | | Detecção | 2026-09-28, hora não apurada | O humano relatou que subir um `.mp4` de 6 GB em `/campanha › Acervo › Gravações › "Enviar gravação"` "está falhando"; o diálogo mostra erro genérico e a mensagem exata na tela é não apurada. | | Diagnóstico | 2026-09-28 | Reprodução read-only em produção: `curl -sSI https://jorgesolla1313.com.br/` → `server: cloudflare`; `POST` de 150 MB para um caminho inexistente (`/__cf-upload-limit-probe-does-not-exist`, não escreve nada) → `413 Payload Too Large` da Cloudflare, encerrando após ~3,2 MB enviados. | -| Correção mergeada | pendente | Correção implementada e verificada localmente; PR aberto neste worktree, CI pendente. | +| Correção mergeada | pendente | Correção implementada e verificada localmente; PR #1382 aberto, CI pendente. | | Deploy | pendente | O merge dispara o deploy; produção depende de approve humano no environment `production`. | | Verificado em prod | pendente — confirmação humana | Pendente a confirmação do humano de que o upload de 6 GB funciona em produção. |