Pular para conteúdo

Etapa 05 — Resetar a replicação (nuke)

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

Esta página é o desenho (porquê e como funciona). O procedimento operacional passo a passo vive no runbook nuke-replication. O sinal que os clientes leem está na etapa 07.

1. Contexto e escopo

Mudanças estruturais nas bi_*, ou o histórico acumulado no Mongo do PowerSync (bucket_data/op_log) crescendo sem parar, exigem de vez em quando zerar o estado replicado (slot de replicação no Postgres + base do PowerSync no MongoDB) e forçar um re-sync limpo nos clientes móveis. É destrutivo e arriscado à mão — encapsulado num serviço auditável, com confirmação anti-acidente e sinal para os clientes reconectarem.

Dentro do escopo: o NukeReplicationService (9 steps); os dois gatilhos (REST + tela /admin); restart opcional do PowerSync via Coolify; audit por step em xls_nuke_replication.

Fora do escopo: o consumo do sinal pelos clientes (chave ultimo_nuke) → etapa 07.

2. Componentes e modelo de dados

flowchart TD
    rest[POST /api/comercial/admin/nuke-replication<br/>Bearer + X-Confirm-Nuke]
    tela[Tela /admin<br/>modal RESETAR + login Google]
    rest --> svc[NukeReplicationService]
    tela --> svc
    svc --> pg[(Postgres: RESET_SLOT)]
    svc --> mongo[(MongoDB PowerSync: DROP_MONGO)]
    svc --> coolify[Coolify API<br/>restart opcional]
    svc --> audit[(xls_nuke_replication<br/>audit por step)]

Audit em xls_nuke_replication (xls_*, local, não sincroniza — BIGSERIAL, V8). Colunas-chave: id (PK), status, iniciado_em/concluido_em, iniciado_por, motivo, step_atual, steps_completados (JSONB default []), detalhes (JSONB), erro_mensagem. Garantias de schema:

  • CHECK chk_nuke_status: status ∈ {PENDENTE, EM_ANDAMENTO, SUCESSO, ERRO}.
  • Índice unique parcial uq_xls_nuke_replication_em_andamento WHERE status = 'EM_ANDAMENTO' (sobre a expressão constante (1)): no máximo um nuke em andamento — um 2º disparo recebe 409.
  • O audit nunca grava a URI do Mongo — só o nome do DB (lido do path da URI).

3. Fluxos e estados

stateDiagram-v2
    [*] --> EM_ANDAMENTO: criar (409 se já houver)
    EM_ANDAMENTO --> SUCESSO: FINALIZAR
    EM_ANDAMENTO --> ERRO: falha em qualquer step
    SUCESSO --> [*]

Os 9 steps idempotentes (executor dedicado, single-thread):

flowchart TB
    V[VALIDAR] --> L[LOCK] --> P[PAUSE] --> SP[SNAPSHOT_PRE]
    SP --> RS[RESET_SLOT] --> DM[DROP_MONGO] --> R[RESUME]
    R --> SA[SAMPLE_POST] --> F[FINALIZAR]

Por que o estado pode ficar parcial (recovery por step): RESET_SLOT roda antes de DROP_MONGO. O drop do slot roda com autoCommit ligado (o Postgres proíbe pg_drop_replication_slot em transação), então uma falha no meio deixa estado parcial — daí o recovery ser passo a passo, não rollback transacional. No FINALIZAR, grava o sinal ultimo_nuke (etapa 07):

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();

4. Contratos

4.1 Gatilhos

Método/rota Confirmação Status
POST /api/comercial/admin/nuke-replication header X-Confirm-Nuke = token (POWERSYNC_NUKE_CONFIRMATION); body {motivo} 202 · 403 confirmação errada · 409 já em andamento · 503 desabilitado
GET …/nuke-replication/{id} — status + steps

A tela /admin (spec 005, modal anti-acidente exigindo digitar RESETAR + CSRF, protegida por login Google — etapa 06) chama o mesmo NukeReplicationService com um clique. A tela não usa o header de confirmação (o modal é a barreira).

4.2 Estratégia de restart

Escolhida pela presença do COOLIFY_API_TOKEN:

Estratégia pause/resume Quando
none (default) no-op — operador para/sobe o PowerSync na mão ambientes sem Coolify
coolify resume() reinicia o recurso PowerSync via API REST do Coolify e faz polling do deployment produção OnPetro

5. Configuração

Env Property Default Papel
POWERSYNC_MONGODB_URI powersync.mongodb.uri vazio → stub (simula o drop) conexão Mongo; o DB sai do path da URI
POWERSYNC_NUKE_CONFIRMATION — vazio → 503 no REST habilita o endpoint REST
COOLIFY_API_TOKEN — vazio → restart manual liga a estratégia coolify
POWERSYNC_COOLIFY_NAME/_UUID — — alvo do restart
POWERSYNC_SLOT powersync.slot auto-discover (via Mongo) slot de replicação
POWERSYNC_BOOTSTRAP_WAIT — 60 espera no SAMPLE_POST

Runbook completo: nuke-replication.

6. Decisões

Nº Decisão
0014 Sinal de reset via bi_configuracao
0013 GRANT ao powersync_role
0003 Login Firebase nas views (protege a tela)

7. Riscos

  • Nuke disparado por engano → modal anti-acidente (RESETAR) + header de confirmação no REST + token configurável; audit por step permite recovery.
  • PowerSync não sobe sync_rules ACTIVE (ex.: GRANT faltando, decisão 0013) → o nuke morre em SNAPSHOT_PRE; conferir privilégios antes.
  • Nuke em horário comercial → freeze de segundos + re-bootstrap simultâneo dos clientes; usar só em janela de baixo tráfego (ver runbook).