From 8b620f9b0460ec5f78872cf106bd6125c80bc7cf Mon Sep 17 00:00:00 2001 From: Leonardo Date: Sat, 13 Jun 2026 17:13:38 -0300 Subject: [PATCH] F6.3: doc de rollback (branch-safety + cenarios pre/pos-DROP) Co-Authored-By: Claude Fable 5 --- database-novo/manual/f6_3_ROLLBACK.md | 99 +++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 database-novo/manual/f6_3_ROLLBACK.md diff --git a/database-novo/manual/f6_3_ROLLBACK.md b/database-novo/manual/f6_3_ROLLBACK.md new file mode 100644 index 0000000..3249653 --- /dev/null +++ b/database-novo/manual/f6_3_ROLLBACK.md @@ -0,0 +1,99 @@ +# F6.3 — Rollback da migração schema-per-tenant + +> Como voltar atrás. Lê isto ANTES de aplicar a F6.3 (o DROP). A regra de ouro: +> **enquanto a F6.3 NÃO foi aplicada, o rollback é trivial e sem perda.** + +## Princípio: a branch é a rede de segurança + +A migração inteira (F3→F6.4) vive na branch `feat/schema-per-tenant`. A `main` +**nunca mudou** o modelo antigo — só recebeu F0/F1/F2, que são **aditivas** +(criam `tenants.slug`, o schema `_tenant_template`, helpers e o gatilho de +provisionamento; não removem nem alteram nada que o app antigo usa). Ou seja: +**`git checkout main` te devolve o app funcionando no modelo public**, desde que +o banco também volte (ver abaixo). + +O único passo IRREVERSÍVEL por si só é o **DROP** (F6.3). Tudo antes dele é +reversível porque os dados continuam **espelhados em public** (a F6.1 COPIA, não +move). Por isso o checkpoint é parar ANTES do DROP. + +--- + +## Cenário 1 — ANTES de aplicar a F6.3 (estado atual) — rollback trivial + +Nada destrutivo foi feito. Public tem todas as tabelas e dados originais. Para +abandonar a migração: + +```bash +# 1. código volta pro modelo antigo +git checkout main + +# 2. banco: derruba os schemas tenant + artefatos da migração +docker exec -i -e PGPASSWORD=postgres supabase_db_agenciapsi-primesakai \ + psql -U supabase_admin -h 127.0.0.1 -d postgres <<'SQL' +DO $$ DECLARE r record; BEGIN + FOR r IN SELECT nspname FROM pg_namespace WHERE nspname LIKE 'tenant\_%' OR nspname='_tenant_template' LOOP + EXECUTE format('DROP SCHEMA %I CASCADE', r.nspname); + END LOOP; +END $$; +-- limpa o registro + config do PostgREST +DELETE FROM public.tenant_schemas; +ALTER ROLE authenticator SET pgrst.db_schemas = 'public, graphql_public'; +NOTIFY pgrst, 'reload config'; +SQL +``` + +⚠️ As FUNÇÕES em public foram reescritas (F6.2) na branch, mas essas mudanças +**não foram aplicadas via migration em `main`** — elas vieram dos arquivos +`manual/f6_2*.sql` aplicados como supabase_admin no banco LOCAL. Se você quer o +banco local 100% igual ao `main`, restaure as funções originais do backup: + +```bash +# restaura o estado public pré-migração (funções, triggers, tudo) +docker exec -i supabase_db_agenciapsi-primesakai psql -U postgres -d postgres \ + < database-novo/backups/pre-F6/public.sql # ou o backup mais antigo (pré-F1) +``` + +Como na prática o banco é LOCAL e descartável, o caminho mais limpo do Cenário 1 +é: **`git checkout main` + `node db.cjs reset` (reinstala schema+seeds do zero)**. + +--- + +## Cenário 2 — DEPOIS de aplicar a F6.3 (DROP já feito) — recuperável, com cuidado + +O DROP removeu as 78 tabelas tenant de public. Os dados VIVOS estão nos schemas +`tenant_`. Há duas situações: + +### 2a) Rollback rápido (logo após o DROP, app quase não rodou nos schemas) +Os dados em public estavam atualizados até o **backup pré-F6.3**. Se quase nada +foi escrito nos schemas depois do DROP, restaure public do backup e volte o código: + +```bash +git checkout main +docker exec -i supabase_db_agenciapsi-primesakai psql -U postgres -d postgres \ + < database-novo/backups/pre-F6.3/public.sql # backup TIRADO antes do DROP +# + derrubar schemas tenant (bloco SQL do Cenário 1) +``` +PERDE: qualquer escrita feita NOS SCHEMAS entre o DROP e o rollback. + +### 2b) Rollback com dados atualizados (app rodou e acumulou dados nos schemas) +Aí os schemas têm a verdade mais nova. Precisa de uma **migração reversa** +(schema → public, o inverso da F6.1), re-adicionando `tenant_id`. Roteiro: +1. Restaure a ESTRUTURA das 78 tabelas em public (do backup pré-F6.3, sem os + dados, ou recriando via o schema dump). +2. Para cada tenant, `INSERT INTO public. (cols + tenant_id) SELECT cols, + '' FROM tenant_.` — o inverso exato do + `manual/f6_1_migrate_data.supabase_admin.sql` (trocar origem/destino e + RE-ADICIONAR a coluna tenant_id com o id do tenant do schema). +3. Resetar sequences, recriar as 9 views + 2 FKs, voltar o código (`git checkout main`). + +Esse caminho é trabalhoso — por isso a recomendação forte: **só aplique a F6.3 +depois de validar o app**, e mantenha o backup pré-F6.3. O DROP é a única coisa +que transforma "trivial" em "trabalhoso". + +--- + +## Checklist antes de aplicar a F6.3 (resumo) +- [ ] App testado no browser (fluxos autenticados sem erro PGRST/4xx). +- [ ] Backup FRESCO: `pg_dump --schema=public > backups/pre-F6.3/public.sql`. +- [ ] Branch commitada (rollback de código = `git checkout main`). +- [ ] Ciente: pós-DROP, public some; a verdade passa a ser os schemas.