# Convex — Loop do `application::exports::worker` (Nov/2025) Documento técnico descrevendo o incidente que derrubava o backend Convex em produção e o passo a passo adotado para corrigir e evitar recorrências. --- ## 1. Resumo Executivo - **Sintoma visível:** o WebSocket `wss://convex.esdrasrenan.com.br/api/1.29.2/sync` caía em código 1006 a cada poucos segundos. - **Causa raiz:** um export agendado automaticamente pelo próprio Convex (`application::exports::worker`) reiniciava toda vez que o backend subia. Durante o “replay” o worker lia documentos (principalmente máquinas e cron jobs antigos) cujo _shape_ já não batia com o esquema atual, causando panic em `shape_inference/src/object.rs:67`. - **Impacto:** o container `sistema_convex_backend` reiniciava em loop. `npx convex deploy` e qualquer CLI que dependesse do backend ficavam presos em `start_push`/`wait_for_schema`. O frontend ficava sem sincronização em tempo real. - **Correção aplicada:** saneamento manual do banco SQLite do Convex (limpeza de cron/exports/records incompatíveis) seguido de um restart completo. O export pendente finalizou com sucesso e o backend estabilizou. --- ## 2. Detecção 1. `docker service logs --tail 400 sistema_convex_backend` mostrava: - Mensagens repetidas do export (`Export gg20vw5b... progress: ...`). - Panics em `application::exports::worker` ou `common::errors` com mensagens `Object with shape ... not in Shape ...`. 2. No navegador e no `npx convex deploy`, as conexões WebSocket encerravam com código 1006. --- ## 3. Diagnóstico / Root Cause Analysis 1. O Convex self-hosted mantém **exports incrementais**. Quando o backend reinicia, o worker reprocessa o export pendente. 2. Em `sistema_convex_data`, a tabela `documents` possuía registros legados: - Cron `hours-usage-alerts-hourly` (já removido do código). - Documentos de máquinas com `metadata`/`customFields` maiores do que o shape compilado. 3. Assim que o export lia esses documentos “fora do shape”, o Convex fazia `panic!`, derrubando o processo principal. 4. Como o export jamais completava, o worker reiniciava e o ciclo se repetia. --- ## 4. Procedimento de Recuperação (Runbook) > ⚠️ **Sempre trabalhar em cima do volume `sistema_convex_data`.** > Todos os comandos abaixo devem ser executados como `root` na VPS. ### 4.1. Parar o backend e fazer backup ```bash docker service scale sistema_convex_backend=0 # Guardar uma cópia datada docker run --rm -v sistema_convex_data:/convex/data \ busybox sh -c 'ts=$(date +%Y%m%d%H%M%S); cp /convex/data/db.sqlite3 /convex/data/db.sqlite3.backup-$ts' ``` ### 4.2. Inspecionar o banco (SQLite) Usamos a imagem `nouchka/sqlite3`, montando o volume: ```bash docker run --rm -it -v sistema_convex_data:/convex/data nouchka/sqlite3 /convex/data/db.sqlite3 ``` Consultas úteis: ```sql -- Verificar o export pendente SELECT json_value FROM documents WHERE json_extract(json_value, '$.name') = 'hours-usage-alerts-hourly'; -- Identificar documentos de máquinas problemáticos SELECT hex(id), hex(table_id), ts FROM documents WHERE json_extract(json_value, '$._id') = 'jn7aq2647e6g69qbrg7q9n6aas7sxqje'; ``` ### 4.3. Sanear dados incompatíveis 1. **Cron legado** ```sql DELETE FROM documents WHERE hex(table_id) = 'C24DDDBFBA00025744D7672E2AC74F91' AND json_extract(json_value, '$.name') = 'hours-usage-alerts-hourly'; ``` 2. **Máquina fora do shape** - Remover índices ligados ao documento: ```sql DELETE FROM indexes WHERE document_id = X'AB88C43B8D0326EBC40F74D4CA564F9E'; ``` - Remover o documento em si: ```sql DELETE FROM documents WHERE id = X'AB88C43B8D0326EBC40F74D4CA564F9E'; ``` 3. (Opcional) Qualquer export/cron adicional pode ser limpado usando o mesmo padrão: `DELETE` na tabela `documents` e correspondentes em `indexes`. ### 4.4. Subir o backend e validar ```bash docker service scale sistema_convex_backend=1 docker service logs --tail 400 -f sistema_convex_backend ``` Critérios de sucesso: - Logs mostram `application::exports::worker ... completed` e, logo após, `No exports requested or in progress`. - Não existem novas linhas `Caught error`/`shape_inference`. - WebSocket `/api/1.29.2/sync` volta a responder **101 Switching Protocols**. --- ## 5. Pós-incidente / Prevenção 1. **Desabilitar jobs pesados por padrão:** já deixamos `REPORTS_CRON_ENABLED=false` e `AUTO_PAUSE_ENABLED=false` nas variáveis. Mantê-las assim até que o Convex publique um fix oficial. 2. **Sempre limpar exports antigos antes de alterar schema:** se um export for rodado manualmente, aguardá-lo completar antes de editar tabelas grandes (`machines`, `ticketWorkSessions` etc.). 3. **Monitorar logs após deploys:** `docker service logs sistema_convex_backend | rg exports::worker` ajuda a verificar se há novos exports presos. 4. **Documentar qualquer alteração direta no SQLite:** registrar no repositório (neste arquivo) os comandos executados, garantindo um histórico completo. --- ## 6. Registro de alterações manuais ### 2025-12-18 — liveChatSessions com versão legada (shape_inference) Motivo: logs do Convex mostravam `shape_inference` recorrente apontando para o documento `pd71bvfbxx7th3npdj519hcf3s7xbe2j` (sessão de chat antiga com status `ACTIVE` em versão histórica). Comandos executados: ```bash # 1) Parar Convex docker service scale sistema_convex_backend=0 # 2) Backup cp /var/lib/docker/volumes/sistema_convex_data/_data/db.sqlite3 \ /var/lib/docker/volumes/sistema_convex_data/_data/db.sqlite3.backup-20251218165717 # 3) Remover versões antigas do documento (mantendo a mais recente) docker run --rm -v sistema_convex_data:/convex/data nouchka/sqlite3 /convex/data/db.sqlite3 \ "DELETE FROM documents \ WHERE json_extract(json_value, '$._id') = 'pd71bvfbxx7th3npdj519hcf3s7xbe2j' \ AND ts < (SELECT MAX(ts) FROM documents \ WHERE json_extract(json_value, '$._id') = 'pd71bvfbxx7th3npdj519hcf3s7xbe2j');" # 4) Subir Convex docker service scale sistema_convex_backend=1 ``` Resultado: versões antigas do documento foram removidas e os erros de `shape_inference` pararam após o restart. --- ## 7. Referências rápidas - Volume Convex: `sistema_convex_data` - Banco: `/convex/data/db.sqlite3` - Contêiner SQLite: `nouchka/sqlite3` - Parar/Subir serviço: `docker service scale sistema_convex_backend=0|1` - Arquivo anterior de referência: `/convex/data/db.sqlite3.pre-export-clean-20251118123551` --- Última revisão: **18/12/2025** — limpeza da versão legada de `liveChatSessions` (`pd71bvfbxx7th3npdj519hcf3s7xbe2j`) e restart do Convex.