Pular para conteúdo

Resetar Powersync

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

Operação destrutiva

Zera o estado replicado (slot do Postgres + base do PowerSync no MongoDB) e força todos os clientes móveis a um full re-sync. Leia até o fim antes de executar pela primeira vez.

O que é

Endpoint/tela admin que zera o estado replicado e força os clientes a refazer o sync a partir do estado atual das tabelas bi_*. Usado para colapsar o histórico acumulado no Mongo (que cresce sem parar). O desenho (9 steps, sinal para os clientes) está em etapa 05.

Quando usar

  • Storage do Mongo passou da faixa de tolerância (limpeza mensal/trimestral).
  • Após mudança de schema em bi_* que invalide os checkpoints.
  • Diagnóstico de divergência entre PG e Mongo (último recurso).

Quando não usar

  • Em horário comercial — clientes online sofrem um freeze de alguns segundos; com muitos clientes, o re-bootstrap simultâneo gera carga.
  • Sem janela de baixo tráfego confirmada com operação.

Pré-requisitos

Variáveis no app (ver deploy para a tabela completa):

  • POWERSYNC_MONGODB_URI — sem ela, o reset só simula o drop.
  • POWERSYNC_NUKE_CONFIRMATION — habilita o endpoint REST (a tela /admin não depende dela). Contrato: o nome do env permanece "nuke".
  • Restart automático (recomendado): COOLIFY_API_TOKEN + POWERSYNC_COOLIFY_NAME (ou _UUID) → a estratégia coolify reinicia o recurso PowerSync sozinha ao fim do reset. Sem o token, o restart é manual.
  • Postgres: a role do app precisa do atributo REPLICATION (o step RESET_SLOT usa pg_drop_replication_slot/pg_terminate_backend). Aplicar uma vez como superuser: ALTER ROLE <role_do_app> WITH REPLICATION;. Sem isso, o reset falha com permission denied to use replication slots.
  • PowerSync: o powersync.yaml precisa ter bi_configuracao no stream recent_data (priority 0). Após mudar o sync_rules, redeploy do recurso PowerSync no Coolify — senão o sinal ultimo_nuke é gravado no PG mas nunca chega no cliente.

Checklist: janela de baixo tráfego confirmada · Telegram de ops sendo monitorado · (se for usar o endpoint REST) Bearer + POWERSYNC_NUKE_CONFIRMATION em mãos.

Passos

Opção A — Tela /admin (recomendado)

  1. Abrir /admin (login Google), clicar em Resetar Powersync.
  2. Confirmar no modal anti-acidente (digitar RESETAR).
  3. Acompanhar os steps na tela de detalhe (polling automático).
  4. Com a estratégia coolify ativa, o PowerSync reinicia sozinho; senão, reiniciar o recurso PowerSync no Coolify (1 clique) ao fim.

Opção B — Endpoint REST

Sem COOLIFY_API_TOKEN (restart manual): parar o PowerSync ANTES. Sem isso, o slot fica ativo e o RESET_SLOT falha (replication slot ... is active) — é a falha mais comum. Parar: docker stop powersync ou kubectl scale deploy/powersync --replicas=0. Subir de volta ao fim. Com a estratégia coolify ativa, o PAUSE/RESUME é automático e este passo é dispensável.

BASE="https://excel.vantroba.xadm.biz"
curl -X POST "$BASE/api/transporte/admin/resetar-powersync" \
     -H "Authorization: Bearer <VANTROBA_XLS_API_TOKEN>" \
     -H "X-Confirm-Nuke: <POWERSYNC_NUKE_CONFIRMATION>" \
     -H "X-Operator-Id: $USER" \
     -H "Content-Type: application/json" \
     -d '{"motivo": "limpeza trimestral 2026Q2"}'
# → 202 { "resetId": N, "status": "EM_ANDAMENTO", "linkStatus": "..." }

X-Operator-Id registra quem disparou o reset (auditoria em xls_resetar_powersync).

Polling: GET $BASE/api/transporte/admin/resetar-powersync/{id} (Bearer) — acompanhar status (EM_ANDAMENTO → SUCESSO). Tempo típico: < 60 s + POWERSYNC_BOOTSTRAP_WAIT.

Histórico: GET $BASE/api/transporte/admin/resetar-powersync?page=0&size=20 (Bearer) — devolve o Page do micronaut-data (content, totalSize e pageable com number/size), mais recentes primeiro. size padrão 20, teto 200.

O header de confirmação permanece X-Confirm-Nuke (contrato).

Verificação

  • Telegram de ops: ✅ RESETAR POWERSYNC CONCLUÍDO em N ms.
  • Smoke em 1 cliente móvel: reabrir o app e confirmar o re-sync (download dos buckets atuais; o bootstrap escala com o volume de bi_*).
  • O sinal ultimo_nuke em bi_configuracao é atualizado no FINALIZAR (faz o cliente Flutter dar disconnectAndClear). Contrato: a chave permanece ultimo_nuke.

Reversão / recovery por step

Sem rollback automático. Falha → status ERRO + Telegram. Resets órfãos em EM_ANDAMENTO (container morreu no meio) são marcados ERRO automaticamente pela recuperação de startup no próximo boot. Recovery manual por step:

Step Estado deixado pelo erro Recovery
VALIDAR/LOCK outro reset em andamento (409 já no POST inicial) aguardar o concorrente terminar e re-chamar
PAUSE PowerSync ainda rodando (sem estratégia coolify, é no-op) sem cleanup; re-chamar
SNAPSHOT_PRE PG consultado, Mongo intacto sem cleanup; re-chamar
RESET_SLOT slot dropado mas não recriado psql: se pg_replication_slots vazio, SELECT pg_create_logical_replication_slot('powersync','pgoutput'); e subir o PowerSync
DROP_MONGO Mongo parcial/intacto (pior caso) mongosh "$URI": use <db>; db.dropDatabase(); subir PowerSync (bootstrap fresh). O <db> vem do path da POWERSYNC_MONGODB_URI
RESUME destrutivo já feito, PowerSync parado reiniciar o recurso PowerSync no Coolify (fallback manual: docker start powersync / kubectl scale deploy/powersync --replicas=1)
SAMPLE_POST/FINALIZAR reset de fato OK, só a finalização falhou SQL de emergência abaixo

SQL de emergência (finalização falhou — fecha o reset e grava o sinal pros clientes):

-- 1. marca o reset como concluído
UPDATE xls_resetar_powersync SET status = 'SUCESSO' WHERE id = N;

-- 2. grava o sinal pros clientes, se marcarUltimoNuke() não gravou.
--    'ultimo_nuke' é contrato (lido pelo cliente Flutter) — não renomear.
INSERT INTO bi_configuracao (id, valor, tipo, sistema, atualizado_em)
VALUES ('ultimo_nuke', NOW()::TEXT, 'TIMESTAMP', TRUE, NOW())
ON CONFLICT (id) DO UPDATE SET valor = EXCLUDED.valor, atualizado_em = NOW();

Falha mais provável — RESET_SLOT por slot ativo: sintoma replication slot ... is active; causa = PowerSync não parou antes. Diagnóstico: SELECT slot_name, active, active_pid FROM pg_replication_slots;. Preferir parar o PowerSync e re-chamar (a estratégia coolify faz PAUSE/RESUME sozinha; sem o token, parar manualmente — ver Passos). Último recurso: kill -9 <active_pid>.

Sintomas pós-reset

Sintoma Causa provável Ação
Cliente móvel não re-sincroniza ao reabrir PowerSync não voltou a rodar docker ps / kubectl get pods; subir o recurso
Bootstrap demorando (> 10 min) volume grande em bi_* ou conexão fraca esperar; checar logs do PowerSync e o storage do Mongo crescendo
Erros de checkpoint nos clientes slot novo à frente do esperado esperar o bootstrap; se persistir, rodar o reset de novo