MÓDULO 6.3

🛡️ Confiabilidade & Monetização

A última milha: depois que a tarefa está hospedada e rodando sozinha, a IA não está mais assistindo para ler erros e consertar. Aqui você fecha esse agentic gap com confiabilidade — log significativo, try/catch nas chamadas externas, retries com backoff e alertas — e fecha o ciclo do dinheiro: transformar a automação num produto que gera receita com pagamentos Stripe. O salto final de "só um workflow" para "um app que vende".

7
Tópicos
~55
Minutos
Avançado
Nível
Prático
Tipo
Progresso do módulo 0% · 0 de 7

🛡️ 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.

☁️ a tarefa roda sozinha na nuvem (sem a IA olhando) Sessão interativa — o loop se cura sozinho erro a IA lê e conserta loop fechado ✓ Hospedada — você recria o loop com plataforma + prompts falha silenciosa (ninguém vê) log · try/catch retries · alertas você é avisado e conserta + redeploy 💳 Stripe — vira produto free + pro = receita

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.

1

🕳️ 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 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

Loop perdido

A IA não lê mais os erros.

Executa ≠ adapta

Roda, mas não se conserta.

Plataforma

Retries, traces, alertas.

Prompting

Erro e log desde o começo.

2

📝 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.

a tarefa falha ✗ "task failed" → não sei nada ✓ "Firecrawl retornou 429 na fonte 3" → sei o código (429), a fonte (3) e o serviço (Firecrawl): acionável

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.

código / prompt (copie e rode)
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

Específico

Serviço, código, item.

Em cada passo

Não só no fim.

Acionável

Dá para agir sem adivinhar.

No trace

Visível no dashboard.

3

🧯 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.

código / prompt (copie e rode)
// 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

Captura

catch impede a morte da task.

Contexto

Loga serviço e código.

Continua

Grava linha parcial.

Crítico só

throw apenas no essencial.

4

🔁 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.

Falha transitória (429 / timeout) — retry resolve tenta 1 ✗ espera 30s tenta 2 ✓ funciona → resolvido sozinho Bug de lógica — retry NÃO resolve tenta 1 ✗ tenta 2 ✗ tenta 3 ✗ → o erro está no código: conserte o bug

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.

código / prompt (copie e rode)
// 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

maxAttempts

Quantas tentativas (ex.: 3).

Backoff

Intervalo cresce (30s, 60s…).

Transitória

Retry é para o passageiro.

Bug ≠ retry

Erro igual 3x = depure.

5

🔔 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

Canais

E-mail, Slack, webhook.

Tipos

Run failed, deploy failed.

Por ambiente

Prod sempre ligado.

Push, não pull

O aviso vem até você.

6

🧑‍🔧 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. 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. 2

    Copiar o erro

    Selecione a mensagem de erro completa (com a stack/contexto que seu log significativo registrou).

  3. 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. 4

    Aplicar o fix

    Deixe o Claude editar o código com a correção identificada; revise a mudança (trust but verify).

  5. 5

    Redeploy

    commit → push → deploy: a versão corrigida sobe para produção na nuvem.

  6. 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.

código / prompt (copie e rode)
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

Trace vermelho

Onde a run quebrou.

Copiar e colar

Você faz a ponte do erro.

Claude diagnostica

Lê o contexto, propõe o fix.

Redeploy + teste

Fecha o loop em verde.

7

💳 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. 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. 2

    Pegar as API keys

    Em Developers → API keys, copie a publishable key (pk_…) e a secret key (sk_…).

  3. 3

    Criar o webhook endpoint

    Aponte para .../api/stripe-webhook escutando checkout.session.completed, customer.subscription.updated e customer.subscription.deleted; copie o webhook secret (whsec_…).

  4. 4

    Rodar a migração no Supabase

    Execute o SQL da migração para criar a tabela subscriptions no Supabase (guarda quem assinou e o status).

  5. 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. 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.

código / prompt (copie e rode)
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

Freemium

Grátis limitado + pro pago.

4 chaves

pk, sk, price ID, whsec.

Webhook

Stripe avisa o seu app.

Vira produto

Workflow → receita.

Fechando confiabilidade: retries automáticos resolvem qual tipo de falha?

📌 Resumo do Módulo

Agentic gap — uma vez hospedada, a tarefa roda mas não se adapta; você recria o loop de cura com plataforma e prompts.
Logging significativo — log específico ("429 na fonte 3"), não genérico; é acionável e aparece no trace.
try/catch nas externas — capture, logue com contexto, continue; grave linha parcial e só lance no crítico.
Retries com backoff — até 3 tentativas com intervalo crescente; resolvem o transitório, não o bug de lógica.
Alertas — e-mail/Slack/webhook em falhas; toda task deployada precisa de um, para você saber antes do usuário.
Loop humano de debug — abra o trace, copie o erro, cole no Claude, aplique o fix, redeploy e teste.
Monetização com Stripe — freemium (grátis limitado + pro pago) via Checkout; 4 chaves, tabela subscriptions e webhook viram receita.

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.