🛡️ Produção de verdade começa aqui
Nos módulos 6.1 e 6.2 você colocou o código na nuvem (GitHub + Trigger.dev) e o blindou (env vars, RLS, auditoria). Falta o que separa um protótipo bonito de um produto que aguenta a vida real: quando algo falha sozinho, você fica sabendo e tem como consertar — e, de quebra, ele gera receita. É a soma de confiabilidade (tópicos 1 a 6) e monetização (tópico 7).
Antes dos sete tópicos, veja o que muda. Numa sessão interativa, a IA lê o erro e conserta na hora — um loop que se cura sozinho. Mas a tarefa hospedada roda sem ninguém olhando: ela executa, mas não se adapta. Você recria esse loop com recursos de plataforma (logs, retries, alertas) e prompts melhores; depois, fecha o ciclo do dinheiro com Stripe.
Diagrama ilustrativo — confiabilidade recria, com plataforma e prompts, o loop de cura que você tinha de graça na sessão interativa; a monetização fecha o ciclo transformando o workflow em produto.
🕳️ O agentic gap revisitado
O que é
Durante o desenvolvimento, você e o Claude Code trabalham num loop que se cura sozinho: a tarefa roda, dá erro, a IA lê o erro na hora e conserta. Mas quando a tarefa é deployada e passa a rodar sozinha — por agenda (cron) ou por evento (webhook) na nuvem — esse loop desaparece. O agentic gap é exatamente essa lacuna: a tarefa hospedada executa, mas não se adapta, e ninguém está lendo os erros.
O que é?Agentic gap — a diferença entre a sessão interativa (a IA está olhando e corrige) e a execução autônoma na nuvem (ninguém está olhando). Falha silenciosa — quando a tarefa quebra mas nada avisa: ela só "para de funcionar" e você descobre tarde.
Concretamente: você fecha o terminal, vai dormir, e às 7h o cron dispara a tarefa. Se a API de uma fonte estiver fora do ar, a tarefa pode travar e morrer — e como o Claude Code não está mais assistindo, a falha passa despercebida até alguém reclamar. A solução não é "torcer": você fecha o gap com recursos da plataforma (retries, traces, alertas) e com prompting melhor (tratamento de erro e logging pedidos desde o primeiro prompt).
Por que aprender
Sem fechar o gap, "rodou na demo" não significa "roda em produção". Uma automação que falha calada é pior do que nenhuma: você acredita que está cuidando de algo que parou há dias. Entender o gap muda a forma como você constrói — você passa a pedir robustez antes do deploy, não depois do incidente.
🎯 Dica prática
Antes de deployar qualquer tarefa, responda a duas perguntas: "se a API X cair, o que acontece?" e "como eu fico sabendo se isso falhar de madrugada?". Se você não tem resposta para as duas, ela ainda não está pronta para produção.
Conceitos-chave
A IA não lê mais os erros.
Roda, mas não se conserta.
Retries, traces, alertas.
Erro e log desde o começo.
📝 Logging significativo
O que é
O Trigger.dev te dá visibilidade (traces) e retries automáticos, mas ele só consegue retentar o que reconhece como falha — e você só consegue diagnosticar o que o log conta. Logging significativo é pedir à IA um log claro em cada passo importante, com contexto específico: não "task failed", mas "Firecrawl retornou 429 na fonte 3". O log vago é inútil; o log específico é acionável.
O que é?Log — uma linha de texto que a tarefa escreve enquanto roda, registrando o que aconteceu. 429 — código HTTP de "muitas requisições" (rate limit). Um log que cita o código e qual fonte falhou diz o que deu errado e onde.
Diagrama ilustrativo — a mesma falha, dois logs. O específico carrega contexto suficiente para você (ou a IA) agir sem adivinhar.
Por que aprender
Quando algo falha às 3h da manhã, o log é tudo o que você terá. Um trace cheio de "ok" e "erro" genéricos te força a reproduzir o problema do zero; um trace com mensagens ricas te diz, em segundos, qual fonte caiu, com qual código, em qual passo. Pedir bons logs desde o primeiro prompt é mais barato do que adicioná-los depois do incidente.
🎯 Objetivo: pedir ao Claude Code logs claros e específicos em cada passo significativo da tarefa.
Revise os arquivos da task <nome-da-task> e adicione um log claro em cada passo significativo. Em vez de mensagens genéricas como "task failed", logue o contexto: serviço, código de status e qual item. Exemplos do que eu quero ver nos logs: - "Firecrawl retornou 429 na fonte 3 (rate limit)" - "Supabase: gravada linha parcial para lead <id> (1 fonte faltando)" - "OpenAI ok: resumo gerado para <empresa> em 1.4s" Use o logger do Trigger.dev (logger.info / logger.warn / logger.error) para que apareçam no trace do dashboard.
✅ Como verificar: rode a task em dev, abra o trace no dashboard do Trigger.dev e confira se cada passo tem uma linha legível com contexto — não só "ok"/"falhou".
Conceitos-chave
Serviço, código, item.
Não só no fim.
Dá para agir sem adivinhar.
Visível no dashboard.
🧯 try/catch nas chamadas externas
O que é
Toda chamada a uma API externa pode falhar — a rede cai, o serviço retorna erro, a resposta vem num formato inesperado. O try/catch é o padrão que envolve essa chamada para que, se ela falhar, a tarefa capture o erro em vez de morrer: você loga o erro com contexto, continua onde for possível e só lança (interrompe de vez) em falhas realmente críticas. É isso que permite a tarefa gravar uma linha parcial em vez de explodir quando uma fonte cai.
O que é?try/catch — uma estrutura de código: o bloco try tenta algo arriscado; se der erro, o bloco catch assume o controle em vez de a tarefa travar. Linha parcial — gravar o que deu certo (3 de 4 fontes) marcando o que faltou, em vez de descartar tudo.
✓ Com try/catch (falha com graça)
- ✓A fonte 3 cai → loga "429 na fonte 3" e continua.
- ✓Grava a linha com 3 fontes, marcando a 4ª como faltante.
- ✓Só interrompe se faltar algo crítico (ex.: o banco está fora).
✗ Sem try/catch (trava tudo)
- ✗A fonte 3 cai → a exceção sobe e mata a task inteira.
- ✗Perde também as fontes que tinham funcionado.
- ✗Falha calada: nada é gravado e o erro vem sem contexto.
Por que aprender
Há um caso real que prova o ponto: o Firecrawl retornou success:false com os resultados sob a chave web em vez de data. Sem tratamento de erro, isso teria quebrado a leitura e derrubado a task. Com o try/catch no lugar, a tarefa detectou o formato inesperado, logou o problema e não travou — gravou o que conseguiu. Tratamento de erro não é luxo: é o que mantém a automação de pé quando o mundo externo se comporta mal.
🎯 Objetivo: falhar com graça — envolver a chamada externa em try/catch, logar com contexto e continuar nos casos não-críticos.
// TypeScript — chamada a uma API externa dentro da task
let dadosFonte = null;
try {
const resp = await fetch(`https://api.<servico>.com/<rota>`, {
headers: { Authorization: `Bearer ${process.env.<CHAVE>}` },
});
if (!resp.ok) {
// falha não-crítica: loga COM contexto e continua
logger.warn(`<Servico> retornou ${resp.status} na fonte ${fonteId}`);
} else {
dadosFonte = await resp.json();
}
} catch (err) {
// erro de rede/timeout: registra e segue sem essa fonte
logger.error(`Falha ao chamar <Servico> (fonte ${fonteId}): ${err.message}`);
}
// grava a linha mesmo parcial — não descarta o que deu certo
await salvarLinha({ ...resto, fonte: dadosFonte ?? "faltando" });
// só lança se faltar algo CRÍTICO (sem isso não há resultado)
if (!dadoEssencial) throw new Error("Dado essencial ausente — abortando");
✅ Como verificar: simule a falha (chave errada / fonte fora) e confirme no trace que a task não trava — ela loga o aviso e grava a linha parcial. Só uma falha realmente crítica deve interromper a run.
Conceitos-chave
catch impede a morte da task.
Loga serviço e código.
Grava linha parcial.
throw apenas no essencial.
🔁 Retries com backoff (vs bugs de lógica)
O que é
Você configura retries na própria definição da task (ex.: até 3 tentativas, com backoff exponencial começando em 30s). Se a tarefa falhar por um motivo passageiro, o Trigger.dev espera e tenta de novo, dobrando o intervalo a cada vez. A regra de ouro: retries resolvem falhas transitórias (timeout, rate limit, instabilidade de rede) — mas não resolvem bugs de lógica no seu código.
O que é?Retry — tentar de novo automaticamente após uma falha. Backoff exponencial — esperar cada vez mais entre tentativas (30s, depois 60s, depois 120s), dando tempo ao serviço de se recuperar e evitando martelá-lo. Falha transitória — um erro temporário que tende a sumir sozinho.
Diagrama ilustrativo — se as 3 tentativas falham igual, o problema não é o momento: é a lógica. Retentar um bug para sempre só queima recursos.
Por que aprender
Saber a diferença evita os dois erros opostos: não ter retries (uma instabilidade boba derruba a run que teria funcionado 30s depois) e confiar demais neles (um bug de lógica é retentado infinitamente, mascarando o problema real e gastando execuções). Se as três tentativas falham com o mesmo erro, pare de retentar e vá depurar — assunto do tópico 6.
🎯 Objetivo: tolerar falhas transitórias configurando retries com backoff exponencial na task.
// trigger/<sua-task>.ts — configuração de retries
export const minhaTask = task({
id: "<id-da-task>",
retry: {
maxAttempts: 3, // até 3 tentativas
minTimeoutInMs: 30_000, // backoff começa em 30s
factor: 2, // exponencial: 30s → 60s → 120s
},
run: async (payload) => {
// ... sua lógica aqui ...
},
});
✅ Como verificar: provoque uma falha transitória (rate limit) e veja no trace o Trigger.dev reagendar a tentativa após ~30s e seguir. Se o MESMO erro repetir nas 3 tentativas, é bug de lógica — não adianta mais retry, vá depurar.
Conceitos-chave
Quantas tentativas (ex.: 3).
Intervalo cresce (30s, 60s…).
Retry é para o passageiro.
Erro igual 3x = depure.
🔔 Alertas (e-mail/Slack/webhook)
O que é
Logs e traces te contam o que aconteceu — se você for olhar. Alertas invertem isso: eles te procuram. No Trigger.dev, em Project Settings > Alerts, você configura notificações por e-mail, Slack ou webhook disparadas em falhas de deploy ou de run, com ambiente e tipo de falha configuráveis. Leva menos de dois minutos para montar.
O que é?Alerta — uma notificação automática quando algo dá errado. Webhook — um endereço (URL) que recebe um aviso da plataforma e pode acionar outra automação. O alerta é o oposto do log: em vez de você ir até a informação, a informação vem até você.
✓ Com alertas
- ✓A run de madrugada falha → você recebe e-mail/Slack na hora.
- ✓Você descobre antes do usuário final reclamar.
- ✓O webhook pode até abrir um ticket ou avisar um canal de equipe.
✗ Sem alertas
- ✗A tarefa quebra e fica dias parada sem ninguém perceber.
- ✗Você só descobre quando um cliente avisa que "parou".
- ✗Confia em "ir olhar o dashboard" — e nunca olha no horário certo.
Por que aprender
Esta é a regra que fecha o agentic gap na prática: toda task deployada precisa ter alerta de falha. Sem isso, você está apostando que vai checar o dashboard exatamente quando der problema — o que nunca acontece. Com alertas, o sistema te chama; você troca "esperança" por "aviso". Como é configurável por ambiente, deixe alertas de produção sempre ligados.
🎯 Dica prática
Adicione "configurar alerta de falha" ao seu checklist de deploy, ao lado de "checar env vars". Vá em Project Settings > Alerts, escolha o canal (Slack costuma ser o mais visível para times), marque o ambiente prod e os tipos de falha (run failed, deploy failed). Dois minutos agora poupam dias de tarefa morta depois.
Conceitos-chave
E-mail, Slack, webhook.
Run failed, deploy failed.
Prod sempre ligado.
O aviso vem até você.
🧑🔧 O loop humano de debug
O que é
O Claude ainda depura — só não automaticamente mais. Em produção, o loop de cura existe, mas com você no meio: a tarefa falha, o alerta chega, e você (o humano) faz a ponte. Abre o trace vermelho no dashboard, copia o erro, cola no Claude ("aqui está o trace que falhou: <erro>, o que está errado e como conserto?"), deixa o Claude identificar o conserto, faz o redeploy e testa. O trace + o Claude dão diagnóstico rápido; o humano só precisa passar o erro adiante.
O que é?Trace — o registro passo a passo de uma run no dashboard; um trace vermelho/failed indica onde a execução quebrou. Redeploy — subir de novo a versão corrigida do código para a nuvem (commit → push → deploy) para que a correção valha em produção.
O loop humano de debug, passo a passo
-
1
Abrir o trace vermelho
No dashboard do Trigger.dev, localize a run que falhou (status failed) e abra o trace para ver em qual passo quebrou.
-
2
Copiar o erro
Selecione a mensagem de erro completa (com a stack/contexto que seu log significativo registrou).
-
3
Colar no Claude e pedir diagnóstico
"Aqui está o trace que falhou: <cole o erro>. O que está errado e como conserto?" — o Claude lê o contexto e propõe a correção.
-
4
Aplicar o fix
Deixe o Claude editar o código com a correção identificada; revise a mudança (trust but verify).
-
5
Redeploy
commit → push → deploy: a versão corrigida sobe para produção na nuvem.
-
6
Testar
Dispare a task de novo (ou espere o próximo cron) e confirme no trace que agora ela passa em verde.
Linha do tempo ilustrativa — o loop é o mesmo da sessão interativa (erro → diagnóstico → fix → redeploy → teste), mas agora você é quem leva o erro até o Claude.
Por que aprender
É aqui que tudo se conecta: o log significativo (tópico 2) torna o trace legível, os alertas (tópico 5) te avisam para abrir esse trace, e os retries (tópico 4) já te dizem se vale depurar (erro igual 3x = bug). O ciclo é rápido porque o trace + o Claude fazem o diagnóstico pesado; sua parte é só a ponte. Dominar esse loop é o que mantém uma automação hospedada viva ao longo das semanas.
🎯 Objetivo: pegar o erro de um trace falho e pedir ao Claude o diagnóstico e o conserto.
Aqui está o trace que falhou: <cole o erro completo copiado do dashboard do Trigger.dev> Contexto: é a task <nome-da-task>, rodou via <cron/webhook> em produção. O que está errado e como conserto? Aplique o fix nos arquivos da task e me explique em uma frase a causa raiz.
✅ Como verificar: aplique o fix proposto, faça o redeploy (commit → push → deploy) e retestе a task — confirme no trace que ela passa em verde. Se voltar a falhar com o mesmo erro, cole o novo trace e repita.
Conceitos-chave
Onde a run quebrou.
Você faz a ponte do erro.
Lê o contexto, propõe o fix.
Fecha o loop em verde.
💳 Monetização com Stripe
O que é
O passo que transforma a automação num SaaS: adicionar pagamentos com Stripe num modelo freemium — um tier grátis limitado (ex.: 2 qualificações de lead por dia) e um tier pro pago (ex.: US$ 29/mês, ilimitado), tudo via Stripe Checkout. A motivação não é só ganhar dinheiro: é limitar o uso para você não pagar a conta de IA dos usuários consumindo sem teto. É o que fecha a transição de "só um workflow" para "um app que gera receita".
O que é?SaaS — software vendido como assinatura. Freemium — tier grátis com limites + tier pago sem limites. Stripe Checkout — a página de pagamento pronta da Stripe. Webhook — endpoint que a Stripe chama para avisar seu app que um pagamento aconteceu.
A boa notícia: você não escreve a integração na mão. Você descreve o resultado e o Claude Code implementa — mas você precisa criar as contas, copiar as quatro chaves e rodar a migração. A sequência abaixo é a parte manual; o código é com o Claude.
Sequência de setup do Stripe
-
1
Criar o produto recorrente
Na Stripe, crie um produto mensal recorrente (ex.: Pro, US$ 29/mês) e copie o price ID (começa com
price_…). -
2
Pegar as API keys
Em Developers → API keys, copie a publishable key (
pk_…) e a secret key (sk_…). -
3
Criar o webhook endpoint
Aponte para
.../api/stripe-webhookescutandocheckout.session.completed,customer.subscription.updatedecustomer.subscription.deleted; copie o webhook secret (whsec_…). -
4
Rodar a migração no Supabase
Execute o SQL da migração para criar a tabela
subscriptionsno Supabase (guarda quem assinou e o status). -
5
Adicionar as 4 chaves no Vercel + redeploy
Cadastre as quatro env vars (publishable, secret, price ID, webhook secret) no Vercel e faça o redeploy para que valham em produção.
-
6
Testar com cartão de teste
Use um cartão de teste da Stripe (ex.:
4242 4242 4242 4242) e confirme que a assinatura aparece como ativa.
Linha do tempo ilustrativa — quatro chaves (publishable, secret, price ID, webhook secret), uma tabela nova e um endpoint de webhook: é o esqueleto de qualquer cobrança por assinatura.
Por que aprender
Sem um limite de uso, cada usuário gratuito pode disparar consumo ilimitado de IA — e a fatura cai no seu colo. O freemium resolve os dois lados: o tier grátis (2/dia) é vitrine e proteção de custo; o tier pro (US$ 29/mês ilimitado) é a receita. Com isso, o que era um workflow técnico vira um produto que se sustenta — o salto final da trilha.
🎯 Objetivo: pedir ao Claude Code a integração de pagamentos com tier grátis e tier pro via Stripe Checkout.
Adicione pagamentos Stripe ao app com modelo freemium: - Tier grátis: até 2 qualificações de lead por dia. - Tier pro: US$ 29/mês, ilimitado, via Stripe Checkout. Use as env vars: STRIPE_PUBLISHABLE_KEY, STRIPE_SECRET_KEY, STRIPE_PRICE_ID, STRIPE_WEBHOOK_SECRET. Crie a rota /api/stripe-webhook escutando checkout.session.completed, customer.subscription.updated e customer.subscription.deleted, e atualize a tabela subscriptions no Supabase conforme o status. Bloqueie o uso acima do limite no tier grátis.
✅ Como verificar: abra a página de preços, clique em assinar e complete o checkout com o cartão de teste (4242…). Confira que a tabela subscriptions marcou o usuário como pro e que o limite de 2/dia some para ele.
Conceitos-chave
Grátis limitado + pro pago.
pk, sk, price ID, whsec.
Stripe avisa o seu app.
Workflow → receita.
Fechando confiabilidade: retries automáticos resolvem qual tipo de falha?
📌 Resumo do Módulo
Próximo:
Você concluiu a Trilha 6 — Produção, Deploy & Segurança. Da mentalidade ao produto que gera receita: o arco completo do Vibe Coding está fechado.