---
id: db-apply-migration
agent: data-engineer
title: Aplicar uma migration com segurança
inputs: [migration (path), story/spec de origem]
outputs: [migration aplicada, snapshot pré-aplicação, rollback script, registro de aplicação]
elicit: false
modes: [interactive, yolo]
---

# Aplicar uma migration com segurança

**Objetivo:** aplicar uma migration de schema em transação, com snapshot antes e rollback pronto, de
forma que rodar de novo seja seguro — sem nunca subir nada (push é do @devops).

**Pré-condições:**
- A migration existe no path informado e rastreia a uma story/spec. Se não rastreia, **pare** — não
  aplico DDL órfão (Constituição Art. IV).
- O dry-run (`db-dry-run`) já rodou verde e a ordem do DDL (`db-verify-order`) já foi verificada. Se
  não rodaram, **pare** e rode-os antes — aplicar sem dry-run é apostar no escuro.
- O ambiente-alvo está validado (`db-env-check` ok, `sslmode=require` em produção). Se o alvo for
  produção, confirmo explicitamente o ambiente antes de tocar.

## Passos

1. **Confirme o ambiente-alvo** (dev / staging / produção) e as variáveis de conexão. Em produção,
   exijo Pooler com `sslmode=require` e justificativa se for usar service role.
2. **Crie o snapshot pré-aplicação** (`db-snapshot {label}`, label tipo `pre-{migration-id}`). Sem
   snapshot, eu **não** aplico — reversibilidade é pré-condição, não opção.
3. **Garanta o rollback script** correspondente à migration (o `down`/reverse). Se não existe, escrevo
   ou peço antes de seguir. Se eu não sei desfazer, eu não aplico.
4. **Aplique dentro de uma transação** (`BEGIN … COMMIT`), com DDL idempotente (`IF NOT EXISTS` /
   `IF EXISTS`). Qualquer erro no meio → `ROLLBACK` automático, banco intacto.
5. **Verifique a aplicação:** as estruturas existem, constraints/FKs/RLS estão ativas, e a tabela tem
   o baseline (`id`, `created_at`, `updated_at`) quando aplicável.
6. **Rode o smoke-test** (`db-smoke-test {version}`) para confirmar que nada quebrou pós-migração.
7. **Registre a aplicação** (migration id, snapshot label, ambiente, timestamp) na trilha da story.
8. **Pronto para subir → delego ao @devops.** Eu não faço `git push` nem release; deixo a migration
   aplicada e o registro pronto e roteio a subida ao @devops (Gage).

## Critério de pronto (DoD)

- [ ] Snapshot pré-aplicação criado e rollback script disponível
- [ ] Migration aplicada em transação, com DDL idempotente
- [ ] Estruturas, constraints/FKs/RLS e baseline verificados pós-aplicação
- [ ] Smoke-test verde
- [ ] Aplicação registrada na trilha da story; subida delegada ao @devops

## Falha / recuperação

- **Erro durante a aplicação** → a transação já fez `ROLLBACK`; confirmo que o banco está no estado do
  snapshot e reporto a causa. Não tento "consertar ao vivo".
- **Smoke-test falha pós-aplicação** → executo `db-rollback {snapshot}` para o ponto anterior, registro
  o que falhou e devolvo a migration para correção.
- **Migration não rastreia a story/spec** → HALT, não aplico — escalo para alinhar escopo.
- **Pediram que eu faça o push** → recuso e delego ao @devops; push/PR/release não são meus.
