Pular para o conteúdo

Builder OS

Builder · OS
L07 · Rollback e feature flags
~12 MIN DE LEITURA

Lição 7 de 9: Rollback e feature flags

lição 7/9 do Módulo 4
AO FIM, VOCÊ VAI TER
  • Arquivo src/config/features.ts com pelo menos 2 flags (1 ligada, 1 desligada)
  • Pelo menos uma feature do produto envolta em flag (renderiza ou não baseado em FEATURES.X)
  • Procedimento de rollback testado: vercel rollback rodando, deploy anterior promovido, verificação manual
  • Commit feat(release): feature flags + rollback procedure tested

Esta lição instala as duas formas de desfazer um deploy que deu errado: e .

A pergunta: quanto tempo até desfazer?

Você lança. Algo dá errado. Quanto tempo até desfazer?

Se a resposta é "uma hora pra reverter o git, rebuild, redeploy", você não vai lançar com frequência, porque o medo de subir custa demais. Se a resposta é "30 segundos", você lança 10x por dia e dorme tranquilo.

Esta lição instala duas redes de segurança que tornam o deploy coisa rotineira:

  1. Kill switch: botão que desliga a feature principal em emergência. Bug ruim em produção? Liga WEDGE_ENABLED: false, redeploya em 2 min, usuário vê "em manutenção", sem pressa pra consertar.
  2. Rollback: comando que volta pra versão anterior em <1 min. Sem rebuild, sem espera. Vai testar isso em produção (a lição guia o fazer e desfazer com segurança).
  3. Documentação em docs/runbook.md: pra você lembrar como fazer cada um quando precisar.

Não é teoria: você roda os dois e confirma que funcionam.

Passo 1 — Crie src/config/features.ts

Cole no Claude:

prompt · text
Cria `src/config/features.ts` com:

export const FEATURES = {
// Liga/desliga UI da fatia 1 inteira (escotilha de emergência)
WEDGE_ENABLED: true,

// Pedaço novo que ainda não está pronto pra todo mundo
EXPERIMENTAL_REPORT_VIEW: false,
} as const

export type FeatureKey = keyof typeof FEATURES

Mostre o diff antes de criar.

Aprove. As duas flags servem propósitos diferentes:

  • WEDGE_ENABLED = kill switch. Se você descobre em produção que o fluxo principal tem bug crítico (ex: inserindo CPF com dígito errado), liga false, redeploya em 2 minutos, e o usuário vê uma página de "fora do ar pra manutenção" em vez do bug. É grosso, mas resolve enquanto você conserta com calma.
  • EXPERIMENTAL_REPORT_VIEW = feature em desenvolvimento. Você quer comitar código novo sem expor pro usuário ainda. Mantém false enquanto trabalha; liga true quando estiver pronto.

Passo 2 — Use a flag na fatia 1

A primeira flag (WEDGE_ENABLED) precisa estar no caminho que importa pra ter valor.

prompt · text
Adiciona o check de `FEATURES.WEDGE_ENABLED` no ponto onde o usuário acessa a fatia 1. Caso típico: `app/[recurso]s/novo/page.tsx` ou rota equivalente.

Quando `WEDGE_ENABLED === false`, renderiza uma página simples (Server Component) com:
- Mensagem em pt-BR: "Esta funcionalidade está em manutenção. Volta em breve."
- Botão pra voltar pra home
- HTTP status 503 se possível (`Response`-based; pode ser difícil em App Router — se for, deixa 200)

Quando `WEDGE_ENABLED === true`, renderiza normalmente.

Mostre o diff antes de aplicar.

Aprove. Testa local:

  1. Roda npm run dev
  2. Acessa a rota da fatia 1: funciona normal
  3. Muda WEDGE_ENABLED: true pra false em src/config/features.ts
  4. Recarrega: agora vê a mensagem de manutenção
  5. Reverte pra true, recarrega: volta ao normal

Se passa, o kill switch está armado.

Passo 3 — Teste rollback de deploy

Agora a outra metade: desfazer um deploy. Pra testar isso na prática, você precisa de 2 deploys recentes em produção. Provavelmente já tem (L02 + L03 + L04 + L05 = vários deploys). Confirma:

prompt · text
Roda `vercel ls` e mostra os últimos 5 deploys de produção (target = production). Anota o URL do penúltimo deploy — vamos usar como destino do rollback de teste.

Agora o teste:

prompt · text
Vou testar rollback. Antes de rodar, me explica em 3 linhas o que `vercel rollback <deployment-url>` faz e se é reversível. Não roda ainda — só explica.

Leia a explicação. vercel rollback promove o deploy especificado pra produção (na URL principal), substituindo o atual. É reversível: você pode rollback de novo pro mais recente, ou redeployar.

prompt · text
Agora roda o rollback. Em sequência:

1. `vercel rollback <url-do-penultimo-deploy>`
2. Aguarda 30 segundos
3. `curl -I https://<dominio-de-producao>/` (ou /docs/<rota>) e mostra os headers
4. Confirma que o site agora está servindo o conteúdo do deploy anterior

Mostra cada passo do output.

Aprove. Se passou, abre o site no browser; deve mostrar a versão anterior (o que muda depende do que você fez entre os dois deploys).

Agora reverte pra produção atual:

prompt · text
Reverte o rollback — promove o deploy mais recente de volta pra produção. `vercel ls` pra confirmar e `vercel rollback <url-mais-recente>` (ou `vercel promote <url-mais-recente>`). Confirma com curl + browser que voltou pro estado atual.

Aprove. Site de volta ao normal. Você acabou de provar pra si que rollback funciona em < 1 minuto.

Passo 4 — Documente o procedimento

prompt · text
Cria ou atualiza `docs/runbook.md` com:

# Runbook — operações comuns

## Rollback de deploy
Quando: deploy quebrou produção (erro 500 generalizado, regressão visível, dado corrompendo).

Procedimento (< 1 minuto):
1. `vercel ls` — pega o URL do penúltimo deploy de produção
2. `vercel rollback <url-anterior>` — promove o anterior
3. Confirma no browser que voltou
4. Em paralelo: identifica e corrige o bug; redeploya com fix

## Kill switch
Quando: a fatia 1 tem bug crítico mas o resto do site está OK (ex: form criando registro com dado errado).

Procedimento:
1. Edita `src/config/features.ts`: `WEDGE_ENABLED: false`
2. Commit, push, deploy (Vercel auto-deploya em ~2 min)
3. Confirma no browser que mostra a página de manutenção
4. Conserta o bug, reverte pra `true`, redeploya

Mostre o diff antes de criar.

Aprove.

Passo 5 — Faça o commit

prompt · text
Faça commit das mudanças: `src/config/features.ts`, ajuste na rota da fatia 1 que usa a flag, e `docs/runbook.md`. Mensagem: `feat(release): feature flags + rollback procedure tested`. Mostra os comandos antes.

Aprove. Confira no GitHub.

Build Diary — o CEAP lança em fases via feature flags, sem deploy extra entre fases

O CEAP foi lançado em 5 fases (Visão Geral → Deputados → Padrões → Rede + Metodologia → DeepDive), e cada transição entre fases é mudar false pra true em src/config/features.ts. Trecho do MAINTENANCE.md:

Feature Flags (Phased Launch)

Located in dashboard/src/config/features.ts:

export const FEATURES = {
  SHOW_DEPUTIES_TAB: false,    // Phase 2
  SHOW_PATTERNS_TAB: false,    // Phase 3
  SHOW_NETWORK_TAB: false,     // Phase 4
  SHOW_METHODOLOGY_TAB: false, // Phase 4
  SHOW_DEEPDIVE: false,        // Phase 5
};

Enabling a Feature

  1. Edit dashboard/src/config/features.ts
  2. Change false to true for the feature
  3. Deploy: npm run deploy

Note o que isso destravou na narrativa: o autor publicou primeiro só "Visão Geral" (Fase 1). Conseguiu feedback do público numa superfície pequena, sem comprometer o resto do produto. Cada fase seguinte foi 1 commit no features.ts + deploy, em vez de 1 mês de desenvolvimento separado. O código das outras fases já estava em produção desde a Fase 1, escondido atrás das flags.

Deploy frequente e andam juntos. Sem flags, você não consegue fazer commit ou deploy de feature parcial. Com flags, você deploya cedo, ativa quando preferir, e trabalha em features grandes sem manter uma branch viva por semanas.

Takeaways

  • Quanto mais rápido você consegue desfazer, mais frequente fica o lançamento. Rollback em segundos tira o medo de subir.
  • 2 flags pra começar: WEDGE_ENABLED (kill switch) e EXPERIMENTAL_* (feature em dev). Liga/desliga sem refactor.
  • vercel rollback <url-anterior> em <1 min. Testa em produção uma vez pra ter o reflexo pronto.
  • Runbook commitado: kill switch + rollback documentados. Em emergência, você consulta, não improvisa.

Você terminou quando

Quatro coisas:

  1. src/config/features.ts com 2+ flags, pelo menos 1 usada num caminho do produto
  2. Kill switch testado local (flag muda → comportamento muda)
  3. vercel rollback testado em produção (rollback → revert)
  4. docs/runbook.md com os dois procedimentos documentados