Bloqueantes — No lanzar hasta resolver
Blocker
Webhook Stripe no idempotente — duplica suscripciones
checkout.session.completed hace un INSERT sin verificar si la suscripción ya existe.
Stripe reintenta webhooks fallidos hasta 72h: un segundo intento crea una segunda fila activa,
cobrando al usuario sin concederle acceso extra. Puede corromper el billing de todos los usuarios de lanzamiento.
api/stripe/webhook.ts:14
// ❌ AHORA — duplica en retry
await supabase.from('subscriptions').insert({ workspace_id, status: 'active' });
// ✅ FIX — upsert idempotente con stripe_subscription_id como clave
await supabase.from('subscriptions').upsert(
{ workspace_id, stripe_subscription_id, status: 'active' },
{ onConflict: 'stripe_subscription_id' }
);
Blocker
SUPABASE_SERVICE_ROLE_KEY expuesto en componentes client-side
La clave
SERVICE_ROLE_KEY (sin prefijo NEXT_PUBLIC_) aparece referenciada en 2 componentes
dentro de app/. Next.js la bundleará en el JS del cliente, exponiendo acceso root a Supabase
a cualquier visitante. Esto bypassea todas las RLS policies.
.env.example — SUPABASE_SERVICE_ROLE_KEY (verificar app/components/*.tsx)
// Buscar y eliminar del bundle cliente:
grep -r "SUPABASE_SERVICE_ROLE_KEY" app/ components/
// Solo debe aparecer en: app/api/**, lib/supabase/server.ts
Blocker
Rutas /api/admin/* sin auth middleware
El
matcher en middleware.ts protege /dashboard y /api/agents,
pero omite /api/admin/:path*. Cualquier usuario anónimo puede acceder a los endpoints de administración
sin autenticación. Con el lanzamiento público, esto es un vector de explotación inmediato.
middleware.ts:3
// ❌ AHORA
export const config = { matcher: ['/dashboard/:path*', '/api/agents/:path*'] };
// ✅ FIX — añadir rutas admin
export const config = { matcher: [
'/dashboard/:path*',
'/api/agents/:path*',
'/api/admin/:path*',
] };
Blocker
Migración 20260616 sin índice ni plan de rollback
ALTER TABLE agent_logs ADD COLUMN execution_metadata jsonb se ejecuta en una tabla proyectada
en 100k+ filas sin índice en workspace_id. Queries de listado serán full-scans.
Además no hay instrucciones de rollback: si falla el despliegue, no se puede revertir la base de datos.
lib/supabase/migrations/20260616_agent_logs.sql
-- ✅ FIX — añadir al final de la migración:
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_agent_logs_workspace
ON agent_logs(workspace_id);
-- ✅ rollback script (20260616_agent_logs_rollback.sql):
ALTER TABLE agent_logs DROP COLUMN IF EXISTS execution_metadata;
DROP INDEX CONCURRENTLY IF EXISTS idx_agent_logs_workspace;
Fixes de Alto Valor — Mejoran el score antes del launch
Alta
Sin tests E2E en el path crítico de conversión
CI verde con 47 unit tests al 31% de cobertura. El flujo completo
registro → onboarding → pago → activación de agente no está cubierto por ningún test E2E.
Un regresión aquí es silenciosa hasta que un cliente real lo reporta.
Implementar 1 test Playwright que cubra este flujo antes del lanzamiento.
tests/e2e/ — directorio vacío
Alta
Health check no verifica dependencias externas
/api/health existe pero solo retorna {"status":"ok"}. No verifica conexión a Supabase,
Stripe reachability, ni cola de jobs de pg_cron. En producción, si Supabase cae, el health check
seguirá verde y el load balancer no drenará el tráfico.
api/health/route.ts
// ✅ FIX — health check con dependencias:
const checks = await Promise.allSettled([
supabase.from('workspaces').select('count').limit(1),
stripe.balance.retrieve(),
]);
return Response.json({ db: checks[0].status, stripe: checks[1].status });
Alta
Variables de entorno sin validación al startup
Si
STRIPE_WEBHOOK_SECRET o SUPABASE_SERVICE_ROLE_KEY están vacías en producción,
la app arranca pero falla silenciosamente en runtime. Añadir validación con Zod o
@t3-oss/env-nextjs que crashee en build time si faltan variables requeridas.
.env.example — 8 variables, 0 validadas
Fortalezas Confirmadas
OK
Firma de webhook Stripe verificada correctamente
stripe.webhooks.constructEvent() se ejecuta antes de procesar cualquier payload.
No hay path de bypass. La separación test/live del commit h7i8j0e está correctamente aplicada.
OK
RLS gap en agent_logs corregido (commit d2e3f6a)
El gap de política RLS en
agent_logs fue identificado y corregido antes de este audit.
Los logs de agentes están correctamente aislados por workspace_id.
OK
CI verde con 47 tests unitarios
GitHub Actions pasa limpio. La lógica core de ejecución de agentes tiene cobertura de unit tests.
Base sólida para añadir E2E sobre ella.