/saas — Constructor SaaS Full-Stack
Desencadenador: /saas [idea] o solo /saas (solicitará la idea)
Salida: Un SaaS completamente desplegado y listo para producción en una URL de Vercel. Autenticación funcional, backend real, datos en vivo, UI hermosa. No una demostración. No un andamio. Un producto real.
VISIÓN GENERAL DEL PIPELINE
RECEPCIÓN → INVESTIGACIÓN (paralela) → PLANIFICAR → ACLARAR → CONSTRUIR → PROBAR → REVISAR → DESPLEGAR
Cada fase controla el acceso a la siguiente. Sin atajos. Sin saltos.
FASE 1 — RECEPCIÓN
Si el usuario ejecutó /saas [idea], extrae la idea del comando.
Si ejecutó /saas sin argumentos, pregunta:
¿Cuál es la idea del SaaS? Descríbela en 1-3 oraciones. Incluye:
- Qué hace
- Para quién es
- Qué problema resuelve
Almacena como IDEA. Confirma de vuelta en una oración antes de continuar.
FASE 2 — INVESTIGACIÓN PARALELA
Inicia dos pistas de investigación simultáneamente usando la herramienta Agent. NO esperes a que una termine antes de comenzar la otra.
Pista A — Inteligencia de Mercado
Genera un agente general-purpose con este prompt:
Investiga el mercado SaaS para esta idea: [IDEA]
Entrega un informe estructurado que cubra:
1. JUGADORES EXISTENTES (5-8 competidores)
- Nombre, URL, niveles de precios, posicionamiento
- Qué hacen bien, qué pierden
- ARR estimado si está disponible
2. TAMAÑO DEL MERCADO Y DEMANDA
- Categoría (CRM, gestión de proyectos, análisis, etc.)
- Estimación del tamaño del mercado
- Tendencia de crecimiento (creciente/estable/decreciente)
- Evidencia de demanda (hilos de Reddit, votos en ProductHunt, ofertas de trabajo)
3. REFERENCIAS DE PRECIOS
- Freemium vs solo pago vs prueba
- Puntos de precio típicos ($/usuario/mes, plano, basado en uso)
- Qué modelos ganan en esta categoría
4. TABLA DE CARACTERÍSTICAS
- Enumera las 10 características más comunes entre los competidores
- Marca cuáles son imprescindibles vs diferenciadores
5. ESPACIO EN BLANCO
- ¿Qué NO están haciendo los competidores?
- ¿Dónde se quejan los usuarios? (revisa G2, Capterra, Reddit)
- ¿Cuál es la oportunidad de cuña?
Devuelve markdown estructurado. Sé específico. Sin rodeos.
Pista B — Investigación de Patrones Técnicos
Genera un segundo agente general-purpose:
Investiga los patrones de implementación técnica para este tipo de SaaS: [IDEA]
Entrega:
1. PATRONES DE MODELO DE DATOS
- ¿Qué tablas/entidades necesita típicamente este tipo de app?
- Relaciones clave y restricciones
- Enfoque de multi-tenencia (org_id por fila vs esquemas separados)
2. PATRONES DE AUTENTICACIÓN
- ¿Este tipo de app necesita inicio de sesión social? ¿Magic link? ¿SSO?
- ¿Solo invitación vs registro abierto?
- Patrones de roles (admin/miembro/visor típico?)
3. PATRONES DE FACTURACIÓN
- ¿Por asiento, basado en uso o plano?
- ¿Estrategia de nivel gratuito que funciona en este espacio?
4. NECESIDADES DE INTEGRACIÓN
- ¿Con qué se integran típicamente las apps en esta categoría?
- ¿Webhooks, Zapier, claves API?
5. RIESGOS TÉCNICOS
- ¿Qué es difícil de construir en esta categoría?
- ¿Qué errores cometen los equipos?
- Consideraciones de rendimiento/escala
Devuelve markdown estructurado. Sé específico.
Espera a que AMBAS pistas se completen antes de continuar.
FASE 3 — PLAN DE ARQUITECTURA
Usando ambas salidas de investigación, produce un plan de construcción estructurado. Escríbelo en .saas-workspace/[project-slug]/PLAN.md.
El plan debe incluir:
3.1 Definición del Producto
## Producto
Nombre: [derivado de la idea, se puede cambiar]
Eslogan: [una línea]
Propuesta de valor central: [una oración]
Usuario objetivo: [persona específica]
## Conjunto de Características MVP (lo que construiremos HOY)
- [Característica 1] — [por qué está en el alcance]
- [Característica 2] — [por qué está en el alcance]
...
## Fuera del Alcance (v1)
- [Característica] — [diferir a v2 porque...]
3.2 Modelo de Datos
Diseña el esquema Postgres completo. Para cada tabla:
- Nombre de la tabla, propósito
- Todas las columnas con tipos, restricciones, valores predeterminados
- Relaciones de clave foránea
- Políticas RLS necesarias
- Índices
Comienza con estas tablas requeridas:
-- Siempre incluir:
profiles (extiende auth.users)
organizations (si multi-tenant)
organization_members (si multi-tenant)
subscriptions (si facturación)
Luego agrega tablas específicas del dominio para el producto.
3.3 Mapa de Rutas
Página de inicio: /
Autenticación: /login /signup /auth/callback
Shell de la app: /app (requiere autenticación)
Características centrales: /app/[característica] (una por característica MVP)
Configuración: /app/settings
Rutas API: /api/... (enumera cada una)
3.4 Confirmación del Stack Tecnológico
Framework: Next.js 15 (App Router, TypeScript)
Base de datos: Supabase (Postgres + Auth + RLS)
Estilos: Tailwind CSS v4 + shadcn/ui
Correo electrónico: Resend (transaccional)
Despliegue: Vercel
Pagos: Stripe (si se necesita facturación)
3.5 Orden de Construcción
Enumera la secuencia exacta: migraciones → autenticación → rutas API → shell de la app → características → página de inicio → plantillas de correo electrónico → pruebas.
FASE 4 — PREGUNTAS DE ACLARACIÓN
Antes de escribir una sola línea de código, revela las brechas. Usa AskUserQuestion para preguntar lo siguiente (agrupa en máximo 4 preguntas por llamada):
Ronda 1 — Alcance del Producto:
- Confirma el nombre (presenta 3 opciones derivadas de la idea)
- ¿Multi-tenant (equipos/orgs) o cuentas de usuario único?
- ¿La v1 necesita pagos/facturación, o es gratuita mientras se construye?
- ¿Alguna característica específica de la investigación que sea imprescindible vs agradable de tener?
Ronda 2 — Diseño y Despliegue (solo preguntar si las respuestas de la Ronda 1 plantean nuevas preguntas):
- ¿Dominio? (o usar subdominio de Vercel por ahora)
- ¿Algún color de marca / preferencias? (predeterminado: sistema verde oscuro Rawgrowth)
- ¿Dirección de correo electrónico del remitente para Resend?
Incorpora las respuestas en el PLAN.md antes de continuar.
FASE 5 — CONSTRUCCIÓN
Configuración Pre-Construcción
Carga estas habilidades antes de escribir cualquier código:
frontend-theme— inyecta el sistema de diseño completo de Rawgrowthui-ux-pro-max— decisiones de diseño, paleta, tipografía- Invoca Magic MCP (
@21st-dev/magic) para cualquier componente complejo
Ubicación del proyecto: Crear en ~/saas-projects/[project-slug]/
Comando de andamiaje:
cd ~/saas-projects
npx create-next-app@latest [project-slug] \
--typescript \
--tailwind \
--eslint \
--app \
--src-dir \
--import-alias "@/*" \
--no-git
cd [project-slug]
Instalar dependencias:
npm install @supabase/supabase-js @supabase/ssr \
resend \
@radix-ui/react-icons \
lucide-react \
class-variance-authority clsx tailwind-merge \
zod \
@hookform/resolvers react-hook-form
# shadcn/ui init
npx shadcn@latest init --defaults
# Añadir componentes shadcn
npx shadcn@latest add button input label card \
dropdown-menu avatar badge separator toast \
dialog sheet tabs form
Configuración de Tailwind v4 — aplica los tokens de frontend-theme a src/app/globals.css.
5.1 Base de Datos y Migraciones
Usa la habilidad add-migration para cada migración.
Migración 1: Esquema central
-- Habilitar RLS en todas las tablas orientadas al usuario
-- profiles: extiende auth.users
CREATE TABLE profiles (
id UUID REFERENCES auth.users(id) ON DELETE CASCADE PRIMARY KEY,
email TEXT NOT NULL,
full_name TEXT,
avatar_url TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Los usuarios pueden ver su propio perfil"
ON profiles FOR SELECT USING (auth.uid() = id);
CREATE POLICY "Los usuarios pueden actualizar su propio perfil"
ON profiles FOR UPDATE USING (auth.uid() = id);
-- Crear perfil automáticamente al registrarse
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO public.profiles (id, email, full_name, avatar_url)
VALUES (
NEW.id,
NEW.email,
NEW.raw_user_meta_data->>'full_name',
NEW.raw_user_meta_data->>'avatar_url'
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();
Migración 2: Organizaciones (si multi-tenant)
CREATE TABLE organizations (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
name TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
owner_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL,
plan TEXT DEFAULT 'free',
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE organization_members (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
org_id UUID REFERENCES organizations(id) ON DELETE CASCADE NOT NULL,
user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL,
role TEXT NOT NULL DEFAULT 'member' CHECK (role IN ('owner', 'admin', 'member')),
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(org_id, user_id)
);
ALTER TABLE organizations ENABLE ROW LEVEL SECURITY;
ALTER TABLE organization_members ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Los miembros pueden ver su organización"
ON organizations FOR SELECT
USING (id IN (
SELECT org_id FROM organization_members WHERE user_id = auth.uid()
));
CREATE POLICY "Los miembros pueden ver la membresía de la organización"
ON organization_members FOR SELECT
USING (org_id IN (
SELECT org_id FROM organization_members WHERE user_id = auth.uid()
));
Migración 3+: Tablas de dominio — crear tablas específicas del producto según el modelo de datos en PLAN.md. Aplica RLS a cada tabla.
5.2 Configuración del Cliente Supabase
src/lib/supabase/client.ts:
import { createBrowserClient } from '@supabase/ssr'
export function createClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
}
src/lib/supabase/server.ts:
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
export async function createClient() {
const cookieStore = await cookies()
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() { return cookieStore.getAll() },
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch {}
},
},
}
)
}
src/middleware.ts — protege todas las rutas /app/*, redirige a los usuarios no autenticados a /login.
5.3 Páginas de Autenticación
Construye /login y /signup como páginas completas (no modales). Aplica frontend-theme:
- Fondo oscuro (#060B08)
- Tarjeta centrada con borde (rgba(255,255,255,0.06))
- Botones CTA verdes (#0CBF6A)
- Campos de correo electrónico + contraseña (+ inicio de sesión social si está configurado)
- Enlace "Olvidé mi contraseña"
- Sin emojis. Limpio, premium, minimalista.
src/app/(auth)/login/page.tsx — formulario de inicio de sesión con Supabase Auth
src/app/(auth)/signup/page.tsx — formulario de registro con flujo de confirmación de correo electrónico
src/app/auth/callback/route.ts — manejador de devolución de llamada OAuth/magic link
Flujo de confirmación de correo electrónico:
- Al registrarse → Supabase envía correo de confirmación (vía Resend SMTP)
- La ruta de devolución de llamada intercambia el código por una sesión
- Redirigir a
/app/dashboarden caso de éxito
5.4 Shell de la Aplicación
src/app/(app)/layout.tsx — diseño autenticado con:
- Barra lateral (plegable en móvil)
- Navegación superior con avatar de usuario + menú desplegable (perfil, configuración, cerrar sesión)
- Migas de pan
- Salida de notificaciones toast
Los elementos de la barra lateral se derivan del mapa de rutas en PLAN.md.
Usa Magic MCP para obtener un componente de barra lateral: busca "dashboard sidebar dark" y adapta a los tokens de frontend-theme.
5.5 Páginas de Características Centrales
Para cada característica en el conjunto de características MVP (de PLAN.md):
- Diseñar primero — consulta Magic MCP para patrones de componentes relevantes
- Capa de datos — los componentes del servidor obtienen datos directamente de Supabase
- Mutaciones — Acciones del Servidor con validación Zod
- Estados de error — cada formulario tiene errores de validación, estados de carga, estados vacíos
- Sin tipos
any— genera tipos TypeScript a partir del esquema de Supabase
Patrón para el componente de servidor de obtención de datos:
import { createClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'
export default async function DashboardPage() {
const supabase = await createClient()
const { data: { user } } = await supabase.auth.getUser()
if (!user) {
redirect('/login')
}
const { data: profile } = await supabase
.from('profiles')
.select('*')
.eq('id', user.id)
.single()
return (
<div>
<h1>Bienvenido, {profile?.full_name || 'Usuario'}</h1>
</div>
)
}
5.6 Integración de Stripe (si se necesita facturación)
npm install @stripe/stripe-js @stripe/react-stripe-js
Configura un webhook de Stripe en /api/webhooks/stripe y las páginas del portal de facturación.
5.7 Página de Inicio
Construye una página de aterrizaje de alta conversión en src/app/page.tsx:
- Hero con eslogan y CTA
- Sección de características
- Prueba social / testimonios
- Pie de página con enlaces
Usa Magic MCP para buscar "landing page dark saas" y adaptarlo.
5.8 Pruebas
Escribe pruebas para:
- Flujo de autenticación (POST /api/auth/*)
- Acciones del Servidor para cada característica
- Consultas de la capa de datos
- Pruebas de extremo a extremo con Playwright para rutas críticas
FASE 6 — REVISIÓN
Antes del despliegue, ejecuta esta lista de verificación:
- ¿Funciona el registro de usuarios?
- ¿Funciona el inicio de sesión?
- ¿Funciona el cierre de sesión?
- ¿Se muestran correctamente los estados vacíos?
- ¿Se muestran correctamente los estados de error?
- ¿Responden los diseños? (móvil, tableta, escritorio)
- ¿Funciona RLS en todas las tablas?
- ¿Se pueden invocar las rutas API de forma independiente?
- ¿Hay algún enlace roto?
- ¿Son correctos los tipos?
Arregla cualquier problema antes del despliegue.
FASE 7 — DESPLIEGUE
Comandos finales:
# Construir para producción
npm run build
# Desplegar en Vercel (asumiendo que la CLI está configurada)
vercel --prod
Después del despliegue, confirma la URL y ejecuta un rápido humo: regístrate, inicia sesión, usa cada característica.
NOTAS FINALES
- Esta habilidad produce un SaaS real. Trátalo como un producto en el que invertirías $10k.
- Sin atajos. Sin código de mierda. Sin componentes rotos.
- El diseño importa. Usa el sistema de diseño Rawgrowth a través de la habilidad
frontend-theme. - Si un componente se siente complejo, usa Magic MCP (
@21st-dev/magic) para generarlo. - Si algo falla, depura. No sigas adelante con código roto.
Construido para Claude Code. Despliega SaaS en minutos, no meses.