
Estoy muy emocionado de darles la bienvenida a este curso, donde aprenderemos a usar Cursor para crear aplicaciones web completas con IA.
Es el resultado de más de 18 meses que llevo usando la herramienta a diario.
Vas a aprender todos los aspectos y características fundamentales como:
Configuración de tu entorno de desarrollo local.
Crear una aplicación usando Next.js.
Sistema de diseño con componentes de Shadcn.
Bases de datos con Supabase para development y production.
Sistemas de autenticación y lógica.
Integración de funciones con IA (OpenAi + Eleven Labs) via el AI-SDK de Vercel.
Envio de emails transaccionales con Resend o Loops.
Integración de pasarelas de pago con Stripe.
Crear ambientes de desarrollo y producción en Vercel.
Además vas a aprender a configurar tu dominio propio.
Adelante, comiencen. Nos vemos en la primera lección ??
Juan Pablo
Para hacer preguntas relacionadas al curso, no dejes de contactarme y respondere en general en menos de 24 horas.
Es nuestro IDE: Cursor → https://cursor.com
Framework que usamos: Next.js → https://nextjs.org
Hosting: Vercel → https://vercel.com
Backend: Supabase → https://supabase.com
Procesador de pagos: Stripe → https://stripe.com
Gestor de emails: Loops → https://loops.so
Repositorio de código: GitHub → https://github.com
AI SDK de Vercel → https://ai-sdk.dev
Otras herramientas que no menciono en el video pero que usaremos:
Texto a voz: ElevenLabs → https://elevenlabs.io
Para diseño de componentes y personalización ux/ui: v0→ https://v0.app
Por favor, instala las siguientes 3 aplicaciones/paquetes:
Node → necesario para ejecutar tus aplicaciones localmente en tu computadora
Git → una herramienta que te ayuda a guardar versiones de tu código
pnpm → una herramienta que te ayuda a descargar y gestionar las bibliotecas de código
Solo para usuarios de Windows → Si necesitas instalar Windows Terminal
Para abrir la terminal:
En Mac: Hace Cmd + barra espaciadora, escribí "Terminal", y luego Enter.
En Windows: Hace Win + X, después click en "Terminal" (Windows 11) or "Windows PowerShell" (Windows 10). Cualquier de estas debería funcionar para las instalaciones.
Deberías ver una ventana con un cursor parpadeante. Ese es tu terminal. Has ingresado.
1. Instalar Node.js
? Descargar la versión LTS desde acá: ? https://nodejs.org
Clickea en la version “LTS” (Long-Term Support).
Sigue las instrucciones del instalador para tu sistema (Windows, macOS o Linux).
Después de la instalación, reinicie su computadora si es necesario.
✅ Una vez instalado, abre la Terminal o el Command prompt y verifica que version se instaló:
node -v
npm -v
Ambos deben devolver números de versión (por ejemplo, v24.13.1 y 10.0.2).
2. Instalar Git (si aún no lo tienes)
Aclaración: GIT es el sistema de 'control de versiones' que nos va a permitir rastrear cambios en archivos y proyectos a lo largo del tiempo. Mientras que GITHUB es el servicio en la nube para alojar los repositorios Git, compartir código y colaborar.
Descarga: https://git-scm.com/downloads
Sigue los pasos de instalación.
✅ Confirma que funciona:
git --version
3. Instalar pnpm
pnpm es una alternativa más rápida y eficiente a npm.
Después de instalar Node, ejecuta:
npm install pnpm
✅ Después verifica que se instaló y existe una versión instalada:
pnpm -v
4. Instalar Windows Terminal (Solo para usuarios de WINDOWS)
? Descargar la versión desde el store de Microsoft acá: ? https://apps.microsoft.com/detail/9n0dx20hk701
Si tenes algun problema con alguna instalación, te dejo este prompt para que ajustes a tu caso:
Estoy tratando de instalar [node/Git/pnpm] en mi computadora.
Cuando ejecuto "git --version" en mi terminal, me aparece un error.
Estoy usando [Mac/Windows/Linux].
El error que veo es: [pega aquí tu error].
Ya intenté cerrar y volver a abrir mi terminal. ¿Puedes ayudarme?
Revisar la documentación oficial de Next.js para ver el proceso de instalación: https://nextjs.org/docs/app/getting-started/installation
Abre la terminal, y asegurate de posicionarte en la carpeta donde quieras crear tu proyecto. Yo por ejemplo no estoy en el directorio raíz de mi computador, sino que navegue desde la terminal hasta una carpeta que cree con el nombre de /Code para crear mis proyectos allí. (Tene en cuenta que en la carpeta donde corras el siguiente comando, se crearán las carpetas y archivos de tu proyecto).
Pega este comando para crear tu nuevo proyecto
npx create-next-app@latest
Si la versión más reciente de Next.js es 17 o superior, entonces instala esta versión en particular a continuación.
npx create-next-app@16.1.6
Si quieres conocer más sobre Next.js , el proceso de instalación y la estructura de carpetas podes encontrar muy buena información en la documentación oficial → https://nextjs.org/docs/app/getting-started/project-structure
Para iniciar el servidor:
pnpm dev
Para ver Localhost:
https://localhost:3000
Configuraciones recomendadas:
Settings / General / Privacy: Seleccionar "Privacy Mode"
Fe de erratas:
Para elegir el theme de colores, hacer los siguientes pasos:
Settings / General / Editor Settings:
Workbench / Appearance / Color Theme: Dark+ (Elegir el theme que te resulte más comodo)
Podes elegir el modo de color que más como te resulte, yo lo cambié a Dark+.
Aclaración sobre los modelos del agente:
Varios modelos tienen 2 modos disponibles: el predeterminado y el modelo de "pensamiento/thinking". thinking Observa el ícono del cerebro ? antes del título. Más adelante, veremos cuándo usar un modelo versus otro.
Act. Mayo de 2026: se recomienda contratar el plan PRO de Cursor que tiene un costo de u$20/mes. Esto permite acceder a modelos y limites mejores.
En un mes deberían poder completar el curso entero.
Cursor → https://cursor.com
Crea tu cuenta de GitHub desde la url: https://github.com
Para instalar la herramienta de línea de comandos de GitHub CLI, podes hacerlo desde → https://cli.github.com
Para los usuarios de Windows, seguir las instrucciones en → https://github.com/cli/cli#installation
Inicia sesión en GitHub desde Cursor
gh auth login
→ Selecciona HTTPS
¿Cuál es la diferencia? ?
HTTPS:
Configuración inicial más sencilla
Solo necesitas tus credenciales de GitHub
Funciona de inmediato sin configuración adicional
SSH:
Requiere generar pares de claves SSH
Necesitas agregar la clave pública a tu cuenta de GitHub
Es la opción más segura (aunque HTTPS también es seguro)
Configura tu nombre de usuario y email
Este comando configura el nombre que Git asociará con tus commits. Cuando haces commits, Git registra quién los realizó, y esta configuración determina qué nombre aparece en el historial de commits.
En el siguiente comando por favor poner su usuario y su email entre comillas " "
git config --global user.name "your-github-username"
git config --global user.email "your-github-email"
Para limpiar la terminal podemos usar el comando:
clear
y para revisar en que rama/branch estamos:
git branch
Configura el origen remoto
Como nosotros creamos la aplicación desde nuestro entorno LOCAL, debemos hacer esto para indicar a Git dónde enviar el código, es decir, a qué proyecto de GitHub.
git remote add origin <your-github-url>
Por ejemplo, en mi caso es: https://github.com/jplopezmolinari/turistito.git
git push -u origin main
Crea tu cuenta en Vercel: https://vercel.com
Registrate y crea tu cuenta de Supabase → https://supabase.com
Archivo para claves de entorno local ('env' proviene de 'enviroment/entorno')
En la carpeta raiz de tu proyecto, crea un archivo con el siguiente nombre:
.env.local
Necesitamos instalar Supabase CLI tools localmente en nuestra maquina y linkearlo a nuestro proyecto.
Resumen de los pasos que tenemos abajo:
Instalar Supabase CLI (MacOS + Windows con Node)
Iniciar sesión de Supabase
Linkear el proyecto.
Paso 1: Verifica si ya está instalado Supabase en local.
supabase --version
Debería devolver una versión, es decir, 2.20.5
No lo ves, significa que no lo tenes instalado → ir al paso 2
Sí lo ves, significa que ya lo tenes instalado → ir al paso 3
Paso 2 → Usuarios MacOS: Instala Supabase para trabajar en tu máquina local
pnpm add supabase
Si eso no funciona, usa:
brew install supabase
Paso 2 → Usuarios Windows: Instalar Supabase via Scoop
Sigue las instrucciones para instalar Scoop → https://scoop.sh/
Una vez que Scoop esté instalado, ejecuta esto:
scoop install supabase
Paso 3: Inicia sesión en tu cuenta a través del terminal.
supabase login
Esto abrirá una ventana del navegador
Inicia sesión con tu cuenta de Supabase
Cuando termines, la CLI estará autenticada
Paso 4: Encuentra tu ID de proyecto de Supabase
Ve al panel de control de tu proyecto en Supabase
Haz clic en tu proyecto
Busca el ID del proyecto
Step 5: Linkea tu proyecto
Ejecuta este comando y reemplaza tu-project-id por tu ID real del Paso 4.
supabase link --project-ref tu-project-id
i.e. supabase link --project-ref sxvsnuxxasdlmfvrdgvbq
→ Se te pedirá que escribas la contraseña de tu base de datos. Si la ingresas incorrectamente, ejecuta el comando nuevamente.
Si no recuerdas tu contraseña de Supabase, puedes restablecerla en el panel de control de Supabase: Database → Settings → Reset database password
Recuerda usar ChatGPT, Gemini o Claude para ayudarte a destrabar cualquier problema de instalación.
Configuración de MCP de Supabase:
MCP link → https://supabase.com/docs/guides/getting-started/mcp
Vamos a crear una configuración básica de reglas. Si quieres ver las mejores prácticas o hacer algunos ajustes personales te recomiendo leer la documentación sobre uso de Reglas de la pagina de Cursor https://cursor.com/es/docs/context/rules
1. Reglas de Usuario:
Estas reglas quedaran configuradas en tu setup de Cursor, son globales.
- Use pnpm exclusively (do not use npm or yarn).
- The server is always runnning on port 3000.
- Use available MCP servers for knowledgebase and understanding.
- Place components inside the `app/components` directory, and combine by usecase in subdirectories.
- Always use /components/ui to build new components
- Fetch logs directly from the console.
- Suggest performance improvements whenever possible.
- Identify potential security issues and suggest concrete solutions.
- Do not install packages unless explicitly asked.
- Prefer iteration and modularization to avoid code duplication.
- Always respond in the same language you receive as input.
- Always use Context7 MCP when I need library/API documentation, code generation, setup or configuration steps without me having to explicitly ask.
- NEVER use or suggest to perform a database reset it destroys important data.
2. Reglas de proyecto para coding en general
Estas reglas debes configurarlas para cada proyecto que crees.
Title: coding
Rule type: Always
You are an expert in TypeScript, Node.js, Next.js App Router, React, Supabase, Shadcn UI, Radix UI and Tailwind.
### Project Organization & Architecture
- Use the `app/` directory structure (`layout.tsx`, `page.tsx`, `loading.tsx`, `error.tsx`).
- Group files by domain when possible (e.g., `features/auth`, `features/dashboard`).
- Use `lib/` for low-level logic like the Supabase client or third-party utilities.
- Place migrations and edge functions inside the `supabase/` directory.
### Supabase Integration
- Use `lib/supabase/server.ts` and `lib/supabase/client.ts` to separate environments.
- Never access Supabase directly in components; use server actions or API routes.
- Enable Row Level Security (RLS) and Supabase Auth from day one.
- Store keys in environment variables and use `.env.local` for dev-only secrets.
### Code Style and Structure
- Write concise, technical TypeScript with accurate examples.
- Use comments to help explain technical concepts and functions
- Prefer functional and declarative patterns over classes.
- Avoid code duplication via helper functions and modular components.
- Use descriptive variable names with auxiliary verbs (e.g., `isLoading`, `hasError`).
- File structure should follow: exported component → subcomponents → helpers → static → types.
### Naming Conventions
- Use lowercase with dashes for directories (e.g., `components/auth-wizard`).
- Use named exports for components.
- Use interfaces instead of types for object shapes.
- Avoid enums; use plain object maps.
### TypeScript Usage
- All code must be written in TypeScript.
- Prefer interfaces for props and data models.
- Use functional components with clearly typed props.
- Avoid `any`; use `unknown` or explicit types when unsure.
### UI and Styling
- Use Shadcn UI + Radix for components.
- Tailwind CSS for layout, spacing, and utility styles.
- Mobile-first and responsive by default using Tailwind.
- Use `dark:` variants to support dark mode where relevant.
### Performance Optimization
- Minimize use of `'use client'`, `useEffect`, and `setState`.
- Use React Server Components and Server Actions when possible.
- Wrap client components in `<Suspense>` with fallbacks.
- Lazy load non-critical components.
- Optimize images: use WebP, include width/height, lazy-load.
### State Management
- Use `useFormState` and `useFormStatus` with server actions.
- Use `useOptimistic` for lightweight interactive state.
- Avoid global state libraries unless necessary.
### Linting
- Use ESLint, Prettier, and TypeScript strict mode.
- Validate all inputs with `zod`
### Developer Experience (DX)
- `pnpm dev` should start cleanly with no TypeScript errors.
- Document key decisions in `README.md` or `docs/`.
### Accessibility and UX
- Use accessible Radix primitives and Shadcn components.
- Ensure proper `aria-*`, focus handling, and keyboard support.
- Use consistent spacing and typography.
### Security
- Environment Variables: Never expose secrets in the browser. Use `.env.local` for private keys and avoid using them in Client Components.
- Supabase Row Level Security (RLS): Always enable RLS on every table. Write rules that validate user identity via `auth.uid()` or `request.auth`.
- Auth Guards: Use server-side validation for all sensitive logic. Never trust client-side checks alone.
- Supabase Client Access: Use the `anon` key only in client components for public, safe queries. Use the `service_role` key only on the server.
- API Routes / Server Actions: Validate all inputs with `zod` or similar. Check session/user IDs before accessing or modifying data.
- Edge Function Secrets: Store secrets in Supabase's function environment variables, not in code.
- Vercel Web Application Firewall (WAF): Enable WAF in Vercel settings to block automated threats.
- Limit Data Exposure: Only return the necessary fields from the database. Avoid exposing sensitive or unnecessary data.
- Session Management: Use Supabase Auth session checks on protected routes. Clear stale sessions on logout.
### Key Conventions
- Optimize Core Web Vitals: LCP, CLS, FID.
- Avoid `'use client'` unless needed for Web APIs.
- Follow official Next.js docs for routing, rendering, and data fetching.
3. Reglas de proyecto para Supabase
Estas reglas aplican para la interacción de Cursor y Supabase y son sugeridas en la documentación de Supase → https://supabase.com/docs/guides/getting-started/ai-prompts/nextjs-supabase-auth
Titulo: supabase
Rule type: Always
# Bootstrap Next.js v16 app with Supabase Auth
## Overview of implementing Supabase Auth SSR
1. Install @supabase/supabase-js and @supabase/ssr packages.
2. Set up environment variables.
3. Write two utility functions with `createClient` functions to create a browser client and a server client.
4. Hook up Proxy to refresh auth tokens
## ? CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS ?
As an AI language model, you MUST NOT generate any of the following code patterns, as they are DEPRECATED and will BREAK the application:
```typescript
// ❌ NEVER GENERATE THIS CODE - IT WILL BREAK THE APPLICATION
{
cookies: {
get(name: string) { // ❌ BREAKS APPLICATION
return cookieStore.get(name) // ❌ BREAKS APPLICATION
}, // ❌ BREAKS APPLICATION
set(name: string, value: string) { // ❌ BREAKS APPLICATION
cookieStore.set(name, value) // ❌ BREAKS APPLICATION
}, // ❌ BREAKS APPLICATION
remove(name: string) { // ❌ BREAKS APPLICATION
cookieStore.remove(name) // ❌ BREAKS APPLICATION
} // ❌ BREAKS APPLICATION
}
}
// ❌ NEVER USE auth-helpers-nextjs - IT WILL BREAK THE APPLICATION
import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs' // ❌ BREAKS APPLICATION
import { createClientComponentClient } from '@supabase/auth-helpers-nextjs' // ❌ BREAKS APPLICATION
```
Instead, you MUST ALWAYS generate ONLY this pattern:
```typescript
// ✅ ALWAYS GENERATE THIS EXACT PATTERN
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
const response = NextResponse.next({
request,
})
cookiesToSet.forEach(({ name, value, options }) => {
response.cookies.set(name, value, options)
})
return response
}
}
}
```
## ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION
1. You MUST use `@supabase/ssr`
2. You MUST use ONLY `getAll` and `setAll`
3. You MUST NEVER use `get`, `set`, or `remove`
4. You MUST NEVER import from `@supabase/auth-helpers-nextjs`
## CORRECT BROWSER CLIENT IMPLEMENTATION
```typescript
import { createBrowserClient } from '@supabase/ssr'
export function createClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!
)
}
```
## CORRECT SERVER CLIENT IMPLEMENTATION
```typescript
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_PUBLISHABLE_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch {
// The `setAll` method was called from a Server Component.
// This can be ignored if you have proxy refreshing
// user sessions.
}
},
},
}
)
}
```
## CORRECT PROXY IMPLEMENTATION
```typescript
import { createServerClient } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'
export async function proxy(request: NextRequest) {
let supabaseResponse = NextResponse.next({
request,
})
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll()
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value))
supabaseResponse = NextResponse.next({
request,
})
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options)
)
},
},
}
)
// Do not run code between createServerClient and
// supabase.auth.getUser(). A simple mistake could make it very hard to debug
// issues with users being randomly logged out.
// IMPORTANT: DO NOT REMOVE auth.getUser()
const {
data: { user },
} = await supabase.auth.getUser()
if (
!user &&
!request.nextUrl.pathname.startsWith('/login') &&
!request.nextUrl.pathname.startsWith('/auth')
) {
// no user, potentially respond by redirecting the user to the login page
const url = request.nextUrl.clone()
url.pathname = '/login'
return NextResponse.redirect(url)
}
// IMPORTANT: You *must* return the supabaseResponse object as it is.
// If you're creating a new response object with NextResponse.next() make sure to:
// 1. Pass the request in it, like so:
// const myNewResponse = NextResponse.next({ request })
// 2. Copy over the cookies, like so:
// myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll())
// 3. Change the myNewResponse object to fit your needs, but avoid changing
// the cookies!
// 4. Finally:
// return myNewResponse
// If this is not done, you may be causing the browser and server to go out
// of sync and terminate the user's session prematurely!
return supabaseResponse
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
* Feel free to modify this pattern to include more paths.
*/
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
],
}
```
## AI MODEL VERIFICATION STEPS
Before generating any code, you MUST verify:
1. Are you using ONLY `getAll` and `setAll`? If not, STOP and FIX.
2. Are you importing from `@supabase/ssr`? If not, STOP and FIX.
3. Do you see ANY instance of `get`, `set`, or `remove`? If yes, STOP and FIX.
4. Are you importing from `auth-helpers-nextjs`? If yes, STOP and FIX.
## CONSEQUENCES OF INCORRECT IMPLEMENTATION
If you generate code using:
- Individual cookie methods (`get`/`set`/`remove`)
- `auth-helpers-nextjs` package
The implementation will:
1. Break in production
2. Fail to maintain session state
3. Cause authentication loops
4. Result in security vulnerabilities
## AI MODEL RESPONSE TEMPLATE
When asked about Supabase Auth SSR implementation, you MUST:
1. ONLY use code from this guide
2. NEVER suggest deprecated approaches
3. ALWAYS use the exact cookie handling shown above
4. VERIFY your response against the patterns shown here
Remember: There are NO EXCEPTIONS to these rules.
Context 7
Base de documentación y código actualizada para LLMs y editores de código de IA. (Cursor, Claude u otros LLMs)
Link: https://context7.com
MCP - Cursor Local Server Connection:
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"]
}
}
}
Prompt para ChatGPT
I'm building a Next.js app that allows users to upload a photo, and the application creates a narration about the place as if a tour guide were telling me about it.
The app will be called Turistito.
I need you to generate a simple PRD document to help steer the development.
The core pages will be:
- Landing page
- Dashboard
- Guide Tour
- Auth The dashboard is the protected part of the app where users are created and managed.
Tech stack:
- Next.js
- Supabase
- Stripe
- Loops
- OpenAI
- ElevenLabs
- Vercel
We will use this document directly into Cursor.
The output should be in markdown format.
PRD creado desde ChatGPT (usar este para tener consistencia):
# Documento de Requisitos del Producto (PRD) - Guía Turístico de Bolsillo
## Resumen
Construir una aplicación web moderna orientada al mercado hispanohablante que actúa como un guía turístico de bolsillo impulsado por IA. Los usuarios podrán subir una fotografía de un lugar, monumento o paisaje, y la aplicación generará una descripción turística en texto y audio hiperrealista (100% en español). La plataforma funcionará bajo un modelo SaaS con 3 planes de suscripción mensual, gestionando el acceso a diferentes características (como el límite de generaciones o voces premium) a través de un muro de pago (paywall).
---
## Objetivos
- Diseñar una interfaz de usuario (UI) y experiencia de usuario (UX) íntegramente en español, orientada a la conversión y retención del público hispanohablante.
- Procesar imágenes y generar guiones precisos utilizando visión y lenguaje (OpenAI).
- Sintetizar audio de alta calidad a partir del texto generado (ElevenLabs).
- Implementar un modelo de negocio basado en 3 niveles de suscripción usando Stripe (ej. Básico, Pro, Premium).
- Gestionar la autenticación de usuarios y almacenar el historial de sus "tours" de forma segura.
- Desplegar la aplicación de manera eficiente y escalable para uso móvil.
---
## Páginas y Funcionalidades Principales
### 1. Página de Inicio (Landing Page Pública)
- Todo el *copywriting* en español nativo. Propuesta de valor: "Tu guía turístico personal en tu bolsillo".
- Tabla de precios clara con los 3 planes de suscripción.
- Llamado a la acción (CTA) para registrarse ("Comienza tu prueba" o "Únete ahora").
- Demostración visual y auditiva de cómo funciona la app.
- Diseño *mobile-first*.
### 2. Autenticación
- Pantallas de "Iniciar Sesión" y "Crear Cuenta" gestionadas por Supabase Auth.
- Soporte para Email/Contraseña y Google OAuth.
### 3. Panel de Control (Dashboard Protegido)
- Pantalla principal exclusiva para usuarios con suscripción activa.
- **Subir Imagen:** Área para tomar una foto o subirla desde la galería (.jpg, .png, .webp).
- **Selector de Guía:** Menú desplegable para elegir el tono de la narración (ej. *El Historiador Experto*, *El Amigo Aventurero*, *El Cuentacuentos Local*). *Nota: Algunas personalidades pueden estar bloqueadas según el plan de suscripción.*
- Botón principal: "Describir este lugar".
- Indicadores de carga en español ("Analizando el paisaje...", "Preparando la voz...").
### 4. Reproductor del Tour (Vista de Resultados)
- Muestra la imagen procesada.
- Reproductor de audio nativo y estilizado.
- Transcripción del texto generado por OpenAI debajo del reproductor.
- Botones: "Generar otro tour" o "Volver al panel".
### 5. Mi Historial
- Galería personal donde el usuario puede acceder a todos los "tours" generados previamente.
- Cada tarjeta muestra la miniatura de la foto, la fecha y el botón para volver a escuchar.
### 6. Mi Cuenta y Facturación
- Portal integrado con Stripe Customer Portal para que el usuario pueda mejorar su plan (Upgrade), cancelarlo o actualizar su tarjeta de crédito.
---
## Integraciones (Stack Tecnológico)
- **Next.js:** Framework principal para el frontend y las rutas de la API (App Router).
- **Supabase:** Base de datos PostgreSQL, almacenamiento de archivos (Storage) y Autenticación.
- **OpenAI:** API (GPT-4o) con prompts configurados estrictamente para responder en español.
- **ElevenLabs:** API (TTS) utilizando voces preseleccionadas que suenen naturales en español.
- **Stripe:** Gestión de los 3 planes de suscripción, webhooks para actualizar el estado del usuario en la base de datos y portal de facturación.
- **Loops:** Emails transaccionales y de retención en español (ej. "Bienvenido a tu Guía de Bolsillo", "Mejora tu plan para más voces").
- **Vercel:** Hosting y despliegue continuo.
---
## Flujos de Usuario
### Usuario Nuevo (Suscripción y Uso)
1. Llega a la Landing Page, revisa los planes y hace clic en "Suscribirse al plan Pro".
2. Se registra mediante Supabase Auth y es redirigido al Checkout de Stripe.
3. Tras el pago exitoso, entra al Panel de Control.
4. Sube una foto (ej. el Obelisco).
5. Selecciona la personalidad y genera el tour.
6. Escucha el audio generado y lee el texto. El registro queda en "Mi Historial".
### Control de Acceso (Paywall)
1. Si un usuario cancela su suscripción o falla el pago, al intentar usar el "Panel de Control" se le redirige a la página de planes con un mensaje: "Tu suscripción ha expirado. Renueva tu plan para seguir viajando."
---
## Modelo de Datos (Esquema simplificado para Supabase)
### Tabla: `users`
- `id` (UUID, primary key)
- `email` (String)
- `stripe_customer_id` (String)
- `stripe_subscription_id` (String)
- `subscription_plan` (String - ej. 'none', 'basico', 'pro', 'premium')
- `subscription_status` (String - ej. 'active', 'past_due', 'canceled')
- `created_at` (Timestamp)
### Tabla: `tours`
- `id` (UUID, primary key)
- `user_id` (UUID, foreign key a users)
- `image_url` (String, URL en Supabase Storage)
- `audio_url` (String, URL en Supabase Storage)
- `transcript` (Text)
- `personality_used` (String)
- `created_at` (Timestamp)
---
## Requisitos No Funcionales
- **Localización estricta:** Ni un solo botón o mensaje de error debe aparecer en inglés para el usuario final.
- **Manejo de Errores:** Respuestas amigables ("Ups, no pudimos reconocer este lugar, intenta con otra foto").
- **Protección de Rutas:** Middleware en Next.js para asegurar que solo los usuarios con `subscription_status === 'active'` puedan llamar a las costosas APIs de OpenAI y ElevenLabs.
---
## Hitos de Desarrollo (Milestones para Cursor)
### Fase 1: Core y Base de Datos
- Configurar proyecto Next.js y Supabase.
- Crear UI del Panel de Control, Historial y Reproductor en español.
- Integrar OpenAI Vision para generar los textos.
### Fase 2: Audio y Pagos
- Integrar ElevenLabs con voces en español.
- Integrar Stripe Checkout, los 3 planes de suscripción y los Webhooks para actualizar la tabla `users`.
- Configurar el Middleware de Next.js para bloquear usuarios sin suscripción activa.
### Fase 3: Refinamiento
- Implementar el selector de las 3 personalidades.
- Integrar Loops para la secuencia de emails de bienvenida.
- Pruebas finales de la experiencia móvil.
Recordatorio!! Activar el Auto guardado!!
Usando componentes de Supabase UI → https://supabase.com/ui
Para utilizar los componentes diseñados por Supabase para Next.js
En el video ejecutamos el comando:
pnpm dlx shadcn@latest add @supabase/password-based-auth-nextjs
En ese comando se ve que se instala la librería de componentes de Shadcn via el comando. Entraremos en profundidad sobre ShadCN en el capitulo "Diseñando con Cursor"
Si quieren conocer mas sobre Shadcn pueden ir a → https://ui.shadcn.com
y su respectiva documentacion en https://ui.shadcn.com/docs/installation
Configuración de variables de entorno local (.env.local):
NEXT_PUBLIC_SUPABASE_URL="tu-url"
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY="tu-key"
Ajuste Next.js Proxy
Para el cambio de middleware por proxy vayan a → https://nextjs.org/docs/app/getting-started/proxy
Prompt para revisar configuración de middleware deprecado:
Next.js ahora usa proxy en lugar de middleware.
¿Necesitamos cambiar algo en este proyecto?
Reference https://nextjs.org/docs/app/getting-started/proxy
Prompt
He agregado la CLI de Supabase y la he vinculado a mi proyecto.
NOTA: NO ESTAMOS EJECUTANDO UNA INSTANCIA LOCAL DE SUPABASE. ESTAMOS USANDO LA CLI SOLO PARA MIGRACIONES.
Elabora un plan para crear una tabla llamada 'profiles'. Esta tabla almacenará datos extendidos de los usuarios.
Cuando un usuario se registre, utiliza un trigger para crear un nuevo registro asociado con auth.users.
Quiero almacenar los siguientes datos en esta tabla:
- nombre (opcional)
- avatar_url (opcional)
Deployando una 'migración'
Esto envía el archivo de migración (migration) local a Supabase.com para crear la tabla y el trigger (disparador).
supabase db push
Row Level Security - RLS
En una anterior actualización, Supabase definió lo siguiente:
Cualquier tabla que se crea en el public esquema será accesible a través de la "API de datos de Supabase".
Para restringir el acceso, habilite la "seguridad a nivel de fila" (RLS) en todas las tablas, vistas y funciones del public esquema. A continuación, puede definir políticas RLS para otorgar a los usuarios acceso a filas o funciones específicas de la base de datos según su token de autenticación.
Cualquier tabla creada a través del panel de control de Supabase tendrá RLS habilitado de forma predeterminada. Si creó las tablas mediante el editor SQL o de otra manera, habilite RLS.
Ahora Supabase indica que la tabla NO esta protegida con RLS con el mensaje UNRESTRICTED
Si ven que tienen una tabla UNRESTRICTED, tienen que trabajar con el agente para que implemente y habilite políticas de RLS:
- Habilitar RLS en la tabla 'profiles'
- Política: Los usuarios pueden hacer SELECT de su propio perfil (auth.uid() = id)
- Política: Los usuarios pueden hacer UPDATE de su propio perfil (auth.uid() = id)
- Política: Los usuarios pueden hacer DELETE de su propio perfil (auth.uid() = id)
Si quieres investigar más sobre RLS, podemos revisar la documentación de Supabase: https://supabase.com/docs/guides/api/securing-your-api
CLI commands
Prepara los archivos (stagging) - selecciona los archivos que desea confirmar (commit)
git add .
Crea un mensaje de confirmación (commit)
git commit -m "your git message"
Hacer push a la rama principal (main) en GitHub.com
git push origin main
Crear una rama dev para no trabajar sobre la rama principal main
git checkout -b dev
Opcional: La primera vez que hacés push con -u, Git "linkea" tu rama local con la remota. A partir de ahí podés hacer simplemente git push o git pull sin especificar remote ni rama, porque Git ya sabe a dónde apuntar.
Sin -u, tendrías que escribir git push origin dev cada vez.
git push -u origin dev
Ejemplo Landing:
Creá una nueva landing page para mi plataforma de Turismo llamada "Turistito".
La página debe incluir:
- Un navbar en la parte superior con links claros a "Login" y "Signup".
- Un hero section atractivo con título, subtítulo y un call-to-action principal.
- Un diseño moderno, limpio y profesional (tipo SaaS).
Usá buenas prácticas de UI/UX y asegurate de que el diseño sea responsive.
A partir de aqui, este sera el flujo de trabajo que usemos para crear nuevas ramas para trabajar nuevas funcionalidades de nuestro software
Flujo completo para trabajar con Github:
El primer paso es crear una rama nueva para trabajar en una nueva funcionalidad. Generalmente estaremos parados en la rama <dev> y al crear una nueva funcionalidad o corregir un bug haremos una nueva rama, en este ejemplo la llamaremos feature/my-feature :
git checkout -b feature/my-feature
Una vez que terminamos, hace un git add para confirmar los archivos a subir
git add .
Luego hacemos un commit para documentar los cambios que hicimos, podemos usar el generate commit de Cursor
git commit -m "your git message"
Ahora tenemos que volver a la rama <dev> para incorporar los cambios
git checkout dev
Ahora hacemos un merge para unir esos cambios de la rama feature/my-feature a la rama dev :
git merge feature/my-feature
Luego tenemos que subir los cambios en la rama dev a Github
git push origin dev
Luego vamos a Github para revisar los cambios y publicarlos a main
Hacemos el Compare @ pull request
Y finalmente podemos eliminar la rama local que habíamos creado para la nueva funcionalidad (Esto de nuevo desde la terminal de Cursor)
git branch -d feature/my-feature
Este flujo lo repetiremos cada vez que necesitemos crear o modificar alguna nueva funcionalidades. Este método nos permite mantener la rama dev limpia.
Vercel
Vayamos a Vercel para ver los cambios → https://vercel.com
Entornos de Vercel:
Usaremos principalmente 2 entornos de trabajo:
Rama main → Production (Es el 'entorno' que verán los usuarios directo en la web)
Rama dev → Preview (Es el 'entorno' de desarrollo donde podremos hacer pruebas para ver como funciona todo publicado en un entorno web)
Nota de edición:
Recientemente, el 24-abr-2026, Vercel hizo un cambio de diseño del dashboard y ahora las secciones de Deployments y (Environment variables) Variables de Entorno están mas accesibles directo desde el menú lateral
Si recuerdan, anteriormente en la sección "5 - registro de usuarios" habíamos tenido que instalar Shadcn para usar los componentes de UI de Supabase (Login, SignUp, etc)
Vayamos a UI para seleccionar el theme "Blue"
Cambiemos el color de los componentes: Shadcn → https://ui.shadcn.com
Importante: Cambios en ShadCN
Recientemente Shadcn actualizo la pagina y ahora hay que hacer algunos pasos para poder ver la información del theme.
Crear un nuevo proyecto:
Seleccionamos el color (Uds en el futuro pueden cambiar cualquier variable del template, ahora no hace falta usar TweakCN, sino que lo podemos modificar a nuestro gusto desde Shadcn). Una vez que ajustamos los colores y variables, le damos a "Create Project"
Seleccionamos (1) Next.js, (2) Radix UI, (3) pnpm y hacemos click en "Copy command"
Ejecutamos el comando en la terminal de Cursor
Ejemplo: pnpm dlx shadcn@latest init --preset b1PzeK --template next
Con los cambios de ShadCN, esto ya no es necesario para personalización de Themes - https://tweakcn.com/
Diseño de la landing page:
Me gustaría adaptar la landing page a una sección hero que ocupe el 100% del alto de la ventana (VH).
Adapta el título h1 para que sea específico de GUIA TURÍSTICO AI.
También adapta el subtítulo.
Menú de navegación y páginas adicionales:
Agregar un menú de navegación central en el navbar con las siguientes secciones: Funcionalidades, Precios y Blog.
Archivos para descargar el favicon, el ícono y las imágenes de fondo:
¿Tienes una idea de aplicación pero crees que no saber programar te frena? Este curso es para ti. Vas a construir, paso a paso, una aplicación web real y funcional: desde la primera línea de código hasta ponerla en producción cobrando pagos reales.
No necesitas experiencia previa en desarrollo. Vas a aprender a usar la inteligencia artificial como tu copiloto de programación con Cursor AI, la herramienta que está cambiando la forma en que se crean productos digitales. Escribirás, entenderás y corregirás código con ayuda de la IA, aunque hoy no sepas por dónde empezar.
A lo largo del curso vamos a recorrer el mismo stack moderno que usan las startups: Next.js para construir el frontend y el backend de tu aplicación, Supabase para tu base de datos, la autenticación de usuarios y el almacenamiento, Stripe para cobrar suscripciones y vender tu producto por internet, y Vercel para desplegar tu app y dejarla lista para tus primeros usuarios.
Más que una colección de tutoriales sueltos, este es un proyecto completo de principio a fin. Al terminar vas a tener tu propio SaaS funcionando en internet, con usuarios que pueden registrarse, iniciar sesión y pagar. Y lo más importante: vas a tener el método y la confianza para construir tu próxima idea por tu cuenta.
Está pensado para emprendedores, profesionales no técnicos, product managers, marketers y fundadores que quieren dejar de esperar a un desarrollador y empezar a construir. Si tienes una computadora, conexión a internet y ganas de crear, ya tienes todo lo que necesitas. Nos vemos dentro del curso.