Capítulo 05 / Migrations, edge functions, gitflow
Workflow
Como o trabalho viaja: do seu laptop, passando pela homologação, até a produção. E o caminho alternativo — quando uma feature precisa pular a fila.
O fluxo padrão
A maior parte do trabalho segue este caminho. Cada seta é uma ação humana, não automática:
↓ git push, abre PR para
dev[simpe-ms-test] → quem mergeia em
dev aplica migrations no QA cloud↓ QA valida, abre PR
dev → main[simpe-ms-dev] → quem mergeia em
main aplica migrations em produção
Cada uma dessas três etapas é manual e intencional. Não tem job de CI fazendo promoção automática — é responsabilidade de quem aprova o merge em cada nível.
Criando uma migration
No seu local, depois de subir o stack:
supabase migration new nome_curto_descritivo
Isso cria supabase/migrations/<timestamp>_nome.sql. Edite com o
SQL que precisa. Para aplicar:
npm run db:reset
db:reset dropa o schema, reaplica todas as
migrations e roda o seed. Demora uns 30 segundos. É a forma "nuclear", mas é a
mais previsível — sempre te deixa em um estado conhecido.
Alternativa mais rápida (só aplica as pendentes, sem zerar dados):
supabase migration up
Use no dia a dia se quiser preservar dados que você inseriu para teste; use
db:reset antes de abrir PR.
Nunca edite uma migration que já foi aplicada em
simpe-ms-test ou simpe-ms-dev. Se precisar consertar
algo, crie uma migration nova com timestamp posterior. Editar uma migration
aplicada quebra o histórico do banco e força recuperação manual.
No seu local, antes de pushar, você pode editar livremente — o
db:reset recria do zero.
Promovendo para simpe-ms-test
Quando seu PR é aprovado e mergeado em dev, alguém precisa aplicar as
novas migrations e fazer deploy das edge functions no cloud de QA. Por convenção,
quem aprova o merge é o responsável por isso.
supabase link --project-ref <ref-do-simpe-ms-test>
supabase db push
supabase functions deploy nome_da_funcao --no-verify-jwt
A CLI mostra o diff antes de aplicar. Confira. Se mudou alguma edge function, faça o deploy também — sem isso, a Vercel vai chamar uma function antiga que pode não bater com o schema novo.
Promovendo para produção
Quando o PR dev → main é aprovado, quem faz o merge precisa
replicar tudo em simpe-ms-dev:
supabase link --project-ref <ref-do-simpe-ms-dev>
supabase db push
supabase functions deploy nome_da_funcao --no-verify-jwt
Confirme com supabase projects list que o relink
foi para o projeto certo antes de rodar o push — é a única
etapa onde uma confusão de projeto pode causar dano real.
Idealmente esse processo acontece junto do merge em main,
para que o deploy automático da Vercel encontre o banco já atualizado.
Cenário especial — feature que pula a fila
Você tem duas features em desenvolvimento paralelo (chamemos de A
e B), ambas com migrations. A está pronta para produção; B ainda
não. Não dá para mergir A em dev porque B já está lá no meio,
e a próxima promoção dev → main arrastaria as duas.
Feature integrada
Branch a partir de dev, desenvolve, PR para dev.
Quando estabilizar, dev → main. Todas as features de
dev vão juntas.
Feature independente
Branch a partir de main, desenvolve, PR direto para
main. Pula a integração em dev — vai sozinha
para produção.
A regra geral: a ordem em que migrations vão para produção é a ordem em
que branches mergeiam em main. Quem mergeia em
dev antes vai junto com tudo o que tiver lá. Quem mergeia em
main direto vai sozinho.
Se A e B mexem no mesmo arquivo (ex: a mesma tabela), pode dar conflito quando
B for rebased contra main depois de A já estar lá. Resolva no rebase
normalmente — o que importa é que as migrations não se misturaram
acidentalmente, mesmo que o código TypeScript tenha conflitos a resolver.
Edge functions
Edge functions vivem em supabase/functions/<nome>/index.ts e
compartilham supabase/deno.jsonc (imports, lints). São Deno, não
Node.
Rodando localmente
supabase start já sobe um container de edge runtime que serve as
functions automaticamente em http://127.0.0.1:54321/functions/v1/.
Mudanças no código exigem restart do container ou usar:
supabase functions serve nome_da_funcao
Esse comando abre um watcher com hot reload. npm run dev:local já
inclui ele.
Deploy
supabase functions deploy nome_da_funcao --no-verify-jwt
Para usar um import map específico:
supabase functions deploy nome_da_funcao --import-map supabase/deno.jsonc
Secrets
São por projeto (test e dev têm secrets separados):
supabase secrets list
supabase secrets set MINHA_VAR=valor
supabase secrets unset MINHA_VAR
No seu local, defina secrets em supabase/.env (não confundir com o
.env da raiz do projeto).
Rollback e consertos
Algo que estava certo no local quebrou ao chegar em simpe-ms-test?
A correção sempre vem em uma nova migration, não na edição da
anterior:
-
Migration corretiva: o estado atual do banco tem um problema
que pode ser corrigido com SQL adicional — ajustar constraint, popular
coluna, renomear trigger. Crie
migration new fix_descricao. - Down-migration: a mudança anterior precisa ser revertida completamente. Crie uma migration que desfaz (DROP TABLE, DROP COLUMN, etc.). Cuidado: dados podem ser perdidos.
O fluxo é o mesmo de sempre: testa local com db:reset, push em test,
valida, replica em prod.