🛡️ La producción de verdad empieza aquí
En los módulos 6.1 y 6.2 pusiste el código en la nube (GitHub + Trigger.dev) y lo protegiste (env vars, RLS, auditoría). Falta lo que separa un prototipo atractivo de un producto que resiste la vida real: cuando algo falla por sí solo, te enteras y tienes cómo corregirlo — y, además, genera ingresos. Es la suma de confiabilidad (temas 1 a 6) y monetización (tema 7).
Antes de los siete temas, mira qué cambia. En una sesión interactiva, la IA lee el error y lo corrige de inmediato: un ciclo que se repara solo. Pero la tarea alojada se ejecuta sin que nadie la supervise: ejecuta, pero no se adapta. Recreas este ciclo con recursos de plataforma (logs, reintentos, alertas) y mejores prompts; después, cierras el ciclo del dinero con Stripe.
Diagrama ilustrativo — la confiabilidad recrea, con la plataforma y los prompts, el ciclo de corrección que tenías gratis en la sesión interactiva; la monetización cierra el ciclo al convertir el workflow en un producto.
🕳️ La brecha agéntica revisitada
Qué es
Durante el desarrollo, tú y el Claude Code trabajan en un loop que se cura solo: la tarea se ejecuta, da error, la IA lee el error en el momento y lo corrige. Pero cuando la tarea es desplegada y empieza a ejecutarse solo — según una agenda (cron) o por un evento (webhook) en la nube — ese loop desaparece. El agentic gap es exactamente esa brecha: la tarea alojada ejecuta, pero no se adapta y nadie está revisando los errores.
¿Qué es?Brecha agéntica — la diferencia entre la sesión interactiva (la IA está mirando y corrige) y la ejecución autónoma en la nube (nadie está mirando). Fallo silencioso — cuando la tarea se rompe pero nadie avisa: simplemente «deja de funcionar» y tú te enteras tarde.
En concreto: cierras el terminal, te vas a dormir y a las 7h el cron activa la tarea. Si la API de una fuente está fuera de servicio, la tarea puede bloquearse y morir — y como Claude Code ya no está supervisando, el fallo pasa desapercibido hasta que alguien se queja. La solución no es «cruzar los dedos»: cierras la brecha con recursos de la plataforma (reintentos, traces, alertas) y con mejores prompts (manejo de errores y logging solicitados desde el primer prompt).
Por qué aprender
Sin cerrar la brecha, «funcionó en la demo» no significa «funciona en producción». Una automatización que falla en silencio es peor que no tener ninguna: crees que estás atendiendo algo que se detuvo hace días. Entender la brecha cambia cómo construyes: empiezas a pedir robustez antes del deploy, no después del incidente.
🎯 Consejo práctico
Antes de desplegar cualquier tarea, responde dos preguntas: "si la API X deja de funcionar, ¿qué pasa?" y "¿cómo me entero si esto falla de madrugada?". Si no tienes respuesta para ambas, todavía no está lista para producción.
Conceptos clave
La IA ya no lee los errores.
Se ejecuta, pero no se corrige solo.
Reintentos, trazas, alertas.
Error y log desde el principio.
📝 Logging significativo
Qué es
O Trigger.dev te da visibilidad (traces) y reintentos automáticos, pero solo puede volver a intentar lo que reconoce cómo falla — y solo puedes diagnosticar lo que cuenta el log. Para un logging significativo, pídele a la IA un log claro en cada paso importante, con contexto específico: no «task failed», sino «Firecrawl devolvió 429 en la fuente 3». Un registro vago no sirve; uno específico permite actuar.
¿Qué es?Log — una línea de texto que escribe la tarea mientras se ejecuta, para registrar lo que ocurrió. 429 — código HTTP de «demasiadas solicitudes» (rate limit). Un log que mencione el código y qué fuente falló dice lo que salió mal y dónde.
Diagrama ilustrativo — el mismo fallo, dos registros. El específico incluye suficiente contexto para que tú (o la IA) puedas actuar sin adivinar.
Por qué aprender
Cuando algo falla a las 3 a. m., el log es todo lo que tendrás. Un trace lleno de "ok" y "error" genéricos te obliga a reproducir el problema desde cero; un trace con mensajes detallados te dice, en segundos, qué fuente falló, con qué código y en qué paso. Pedir buenos logs desde el primer prompt es más barato que agregarlos después del incidente.
🎯 Objetivo: pedirle a Claude Code logs claros y específicos en cada paso significativo de la tarea.
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.
✅ Cómo verificar: ejecuta la task en dev, abre el trace en el dashboard de Trigger.dev y comprueba que cada paso tenga una línea legible con contexto, no solo "ok"/"falló".
Conceptos clave
Servicio, código, elemento.
No solo al final.
Se puede actuar sin adivinar.
Visible en el dashboard.
🧯 try/catch en las llamadas externas
Qué es
Toda llamada a una API externa puede fallar: la red se cae, el servicio devuelve un error, la respuesta llega en un formato inesperado. El try/catch es el patrón que envuelve esa llamada para que, si falla, la tarea capture el error, en lugar de desaparecer: registras el error con contexto, continúas donde sea posible y solo lanza (se detiene por completo) ante fallos realmente críticos. Eso es lo que permite que la tarea guarde una fila parcial en lugar de colapsar cuando una fuente deja de funcionar.
¿Qué es?try/catch — una estructura de código: el bloque try intenta algo arriesgado; si da error, el bloque catch toma el control en lugar de dejar que la tarea se bloquee. Línea parcial — guardar lo que funcionó (3 de 4 fuentes), indicando lo que faltó, en vez de descartarlo todo.
✓ Con try/catch (falla correctamente)
- ✓La fuente 3 falla → registra "429 en la fuente 3" y continúa.
- ✓Registra la fila con 3 fuentes y marca la 4.ª como faltante.
- ✓Solo se interrumpe si falta algo crítico (p. ej., la base de datos está fuera de servicio).
✗ Sin try/catch (se bloquea todo)
- ✗La fuente 3 falla → la excepción se propaga y mata toda la task.
- ✗También pierdes las fuentes que habían funcionado.
- ✗Fallo silencioso: no se guarda nada y el error llega sin contexto.
Por qué aprender
Hay un caso real que demuestra el punto: el Firecrawl devolvió success:false con los resultados bajo la clave web en lugar de data. Sin manejo de errores, esto habría interrumpido la lectura y detenido la task. Con el try/catch en su lugar, la tarea detectó el formato inesperado, registró el problema y no se bloqueó — guardó lo que pudo. El manejo de errores no es un lujo: es lo que mantiene la automatización en pie cuando el mundo externo se comporta mal.
🎯 Objetivo: fallar con elegancia: envolver la llamada externa en try/catch, registrar con contexto y continuar en los casos no 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");
✅ Cómo verificar: simula el fallo (clave incorrecta / fuente caída) y confirma en el trace que la task no se bloquea — registra la advertencia y guarda la línea parcial. Solo un fallo realmente crítico debe interrumpir la ejecución.
Conceptos clave
catch evita que la tarea muera.
Registra el servicio y el código.
Registra una fila parcial.
usa throw solo en lo esencial.
🔁 Retries con backoff (vs. bugs de lógica)
Qué es
Tú configuras reintentos en la propia definición de la task (ej.: hasta 3 intentos, con backoff exponencial empezando en 30s). Si la tarea falla por un motivo pasajero, Trigger.dev espera y vuelve a intentarlo, duplicando el intervalo cada vez. La regla de oro: los reintentos resuelven fallas transitorias (tiempo de espera agotado, límite de solicitudes, inestabilidad de red), pero no resuelven errores de lógica en tu código.
¿Qué es?Reintento — volver a intentarlo automáticamente después de un fallo. Backoff exponencial — esperar cada vez más entre intentos (30s, luego 60s y después 120s), para darle tiempo al servicio de recuperarse y evitar saturarlo. Fallo transitorio — un error temporal que suele desaparecer por sí solo.
Diagrama ilustrativo — si los 3 intentos fallan igual, el problema no es el momento: es la lógica. Volver a intentar un bug para siempre solo consume recursos.
Por qué aprender
Saber la diferencia evita los dos errores opuestos: no tener reintentos (una inestabilidad menor hace fallar la ejecución que habría funcionado 30s después) y confiar demasiado en ellos (un bug de lógica se vuelve a intentar infinitamente, ocultando el problema real y consumiendo ejecuciones). Si los tres intentos fallan con el mismo error, deja de reintentarlo y depura; ese es el tema 6.
🎯 Objetivo: tolerar fallas transitorias configurando reintentos con backoff exponencial en la 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 ...
},
});
✅ Cómo verificar: provoca un fallo transitorio (límite de solicitudes) y revisa en el trace si Trigger.dev reprograma el intento después de ~30s y continúa. Si se repite el MISMO error en los 3 intentos, es un bug de lógica: más reintentos no ayudarán, ve a depurar.
Conceptos clave
Cuántos intentos (p. ej., 3).
El intervalo aumenta (30s, 60s…).
El reintento es para el pasajero.
El mismo error 3 veces = depura.
🔔 Alertas (correo electrónico/Slack/webhook)
Qué es
Los logs y las trazas te cuentan qué pasó — si vayas a mirar. Alertas invierten eso: te buscan. En Trigger.dev, en Project Settings > Alerts, configuras notificaciones por correo electrónico, Slack o webhook activadas ante fallas de deploy o de run, con el entorno y el tipo de falla configurables. Se configura en menos de dos minutos.
¿Qué es?Alerta — una notificación automática cuando algo sale mal. Webhook — una dirección (URL) que recibe un aviso de la plataforma y puede activar otra automatización. La alerta es lo opuesto al log: en vez de ir tú a buscar la información, la información llega a ti.
✓ Con alertas
- ✓El run de madrugada falla → recibes un correo/Slack de inmediato.
- ✓Tú descubres antes del usuario final se queje.
- ✓El webhook incluso puede abrir un ticket o avisar a un canal del equipo.
✗ Sin alertas
- ✗La tarea falla y queda detenida durante días sin que nadie se dé cuenta.
- ✗Solo te enteras cuando un cliente avisa que "dejó de funcionar".
- ✗Confía en "ir a revisar el dashboard" — y nunca lo revisa en el momento adecuado.
Por qué aprender
Esta es la regla que cierra el agentic gap en la práctica: toda task desplegada debe tener una alerta de fallo. Sin esto, apuestas a que revisarás el dashboard justo cuando surja un problema —algo que nunca pasa—. Con alertas, el sistema te avisa; cambias la "esperanza" por el "aviso". Como se configura por entorno, deja siempre activadas las alertas de producción.
🎯 Consejo práctico
Agrega «configurar alerta de fallas» a tu checklist de deploy, junto a «verificar env vars». Ve a Project Settings > Alerts, elige el canal (Slack suele ser el más visible para los equipos), marca el entorno prod y los tipos de fallo (run failed, deploy failed). Dos minutos ahora te ahorran días de tareas muertas después.
Conceptos clave
Correo electrónico, Slack, webhook.
Run fallido, deploy fallido.
Prod siempre encendido.
El aviso te llega a ti.
🧑🔧 El ciclo humano de depuración
Qué es
Claude todavía depura; solo que no automáticamente más. En producción, el ciclo de corrección existe, pero contigo en medio: la tarea falla, llega la alerta y tú (el humano) haces de puente. Abre el trace rojo en el dashboard, copia el error, pégalo en Claude ("aquí está el trace que falló: <erro>, ¿qué está mal y cómo lo arreglo?"), deja que Claude identifique la solución y haz el redeploy y prueba. El trace + Claude permiten diagnosticar rápido; el humano solo tiene que pasar el error.
¿Qué es?Trace — el registro paso a paso de una run en el dashboard; un trace rojo/failed indica dónde falló la ejecución. Redeploy — volver a subir a la nube la versión corregida del código (commit → push → deploy) para que la corrección se aplique en producción.
El loop humano de depuración, paso a paso
-
1
Abrir el trace rojo
En el dashboard de Trigger.dev, localiza la run que falló (status failed) y abre el trace para ver en qué paso se produjo el error.
-
2
Copiar el error
Selecciona el mensaje de error completo (con el stack/contexto que registró tu log significativo).
-
3
Pegar en Claude y pedir un diagnóstico
"Aquí está el trace que falló: <pega el error>. ¿Qué está mal y cómo lo arreglo?" — Claude lee el contexto y propone la corrección.
-
4
Aplicar el fix
Deja que Claude edite el código con la corrección identificada; revisa el cambio (confía, pero verifica).
-
5
Redeploy
commit → push → deploy: la versión corregida sube a producción en la nube.
-
6
Probar
Vuelve a activar la task (o espera al próximo cron) y confirma en el trace que ahora pasa en verde.
Línea de tiempo ilustrativa: el loop es el mismo de la sesión interactiva (error → diagnóstico → fix → redeploy → prueba), pero ahora tú es quien lleva el error hasta Claude.
Por qué aprender
Es aquí donde todo se conecta: el log significativo (el tema 2) hace que el trace sea legible; los alertas (el tema 5) te avisan que abras ese trace, y los reintentos (el tema 4) ya te indican si vale la pena depurar (el mismo error 3 veces = bug). El ciclo es rápido porque el trace + Claude hacen el diagnóstico pesado; tu parte es solo el puente. Dominar este ciclo es lo que mantiene viva una automatización alojada durante semanas.
🎯 Objetivo: tomar el error de un trace fallido y pedirle a Claude el diagnóstico y la solución.
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.
✅ Cómo verificar: aplica el fix propuesto, vuelve a desplegar (commit → push → deploy) y prueba de nuevo la task; confirma en el trace que pase a verde. Si vuelve a fallar con el mismo error, pega el nuevo trace y repite.
Conceptos clave
Dónde falló la run.
Conectas con el error.
Lee el contexto y propone el fix.
Cierra el loop en verde.
💳 Monetización con Stripe
Qué es
El paso que convierte la automatización en un SaaS: agregar pagos con Stripe en un modelo freemium — un tier gratuito limitado (p. ej., 2 calificaciones de lead al día) y un tier pro de pago (p. ej., US$ 29/mes, ilimitado), todo mediante Stripe Checkout. La motivación no es solo ganar dinero: es limitar el uso para que no pagues la cuenta de IA de los usuarios que la consumen sin límite. Es lo que completa la transición de «solo un workflow» a «una app que genera ingresos».
¿Qué es?SaaS — software vendido mediante una suscripción. Freemium — nivel gratuito con límites + nivel de pago sin límites. Stripe Checkout — la página de pago de Stripe lista. Webhook — endpoint que Stripe llama para avisarle a tu app que ocurrió un pago.
La buena noticia: no escribes la integración a mano. Describes el resultado y el Claude Code implementa — pero tú tienes que crear las cuentas, copiar las cuatro claves y ejecutar la migración. La secuencia de abajo es la parte manual; el código lo hace Claude.
Secuencia de configuración de Stripe
-
1
Crear el producto recurrente
En Stripe, crea un producto mensual recurrente (p. ej., Pro, US$ 29/mes) y copia el price ID (empieza con
price_…). -
2
Obtener las API keys
En Developers → API keys, copia la publishable key (
pk_…) e a secret key (sk_…). -
3
Crear el endpoint del webhook
Apunta a
.../api/stripe-webhookescuchandocheckout.session.completed,customer.subscription.updatedecustomer.subscription.deleted; copia el webhook secret (whsec_…). -
4
Ejecutar la migración en Supabase
Ejecuta el SQL de la migración para crear la tabla
subscriptionsen Supabase (guarda quién se suscribió y el estado). -
5
Agregar las 4 claves en Vercel + redeploy
Registra las cuatro variables de entorno (publishable, secret, price ID, webhook secret) en Vercel y vuelve a hacer el deploy para que se apliquen en producción.
-
6
Probar con una tarjeta de prueba
Usa una tarjeta de prueba de Stripe (ej.:
4242 4242 4242 4242) y confirma que la suscripción aparezca como activa.
Línea de tiempo ilustrativa: cuatro claves (publishable, secret, price ID, webhook secret), una tabla nueva y un endpoint de webhook: es el esqueleto de cualquier cobro por suscripción.
Por qué aprender
Sin un límite de uso, cada usuario gratuito puede generar un consumo ilimitado de IA, y la factura te llega a ti. El modelo freemium resuelve ambos lados: el nivel gratis (2/día) sirve como vitrina y protección de costos; el nivel pro (US$ 29/mes ilimitado) genera los ingresos. Así, lo que era un workflow técnico se convierte en un producto que se sostiene por sí misma — el salto final de la ruta.
🎯 Objetivo: pedirle a Claude Code la integración de pagos con un tier gratis y un tier pro mediante 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.
✅ Cómo verificar: abre la página de precios, haz clic en suscribirte y completa el checkout con la tarjeta de prueba (4242…). Comprueba que la tabla subscriptions marcó al usuario como pro y que el límite de 2/día desaparezca para él.
Conceptos clave
Gratis limitado + pro de pago.
pk, sk, price ID, whsec.
Stripe avisa a tu app.
Workflow → receta.
Al cerrar la confiabilidad: los retries automáticos resuelven qué tipo ¿de error?
📌 Resumen del módulo
Siguiente:
Completaste la Ruta 6 — Producción, Deploy y Seguridad. Desde la mentalidad hasta el producto que genera ingresos: el arco completo de Vibe Coding está cerrado.