Crea una App de Gastos con Next.js, PostgreSQL y OpenAI Vision paso a paso
Crear proyectos web hoy en día es relativamente fácil gracias a las herramientas de IA que nos permiten construir el proyecto completo, ya sea backend, frontend e incluso la base de datos. En este tutorial vamos a crear desde cero una app de seguimiento de gastos llamada Expense Tracker, la desplegaremos en producción y aprenderemos a integrar OpenAI Vision para escanear facturas automáticamente.
¿Qué vamos a construir?
La app permite a los usuarios registrarse, acceder a un panel de control y registrar sus gastos de dos formas: manualmente o escaneando una factura. La funcionalidad estrella es el escáner: el usuario arrastra una foto de su recibo, la app la sube a la nube, la procesa con IA y extrae automáticamente:
- El total del gasto
- La empresa o comercio
- La categoría del gasto (alimentos, construcción, transporte, etc.)
- La fecha de la factura
Todo queda guardado en la base de datos junto con la imagen original en Cloudinary.
Stack utilizado
- Next.js — Framework de JavaScript para frontend y backend en un solo proyecto
- SQLite → PostgreSQL — Base de datos local para desarrollo, PostgreSQL para producción
- Prisma — ORM para modelar y consultar la base de datos
- OpenAI Vision (GPT-4o) — Para interpretar imágenes de facturas y categorizar gastos
- Cloudinary — Servicio gratuito para alojar las imágenes subidas
- Claude Code — Herramienta de IA para desarrollar el proyecto
- Seenode — Plataforma para el deploy del frontend y la base de datos
- GitHub CLI — Para subir el proyecto a GitHub desde la terminal
Paso 1: Crear el proyecto con Claude Code
Antes de escribir código, es importante describirle a la IA lo que queremos construir de forma clara y concisa. En este caso le pedimos:
- Una app de rastreador de gastos con OCR
- Categorización automática de gastos
- Seguimiento de presupuesto y alertas
- Exportación de reportes
- Que sea una demo, para evitar que genere una planificación demasiado extensa
Claude Code genera automáticamente el proyecto con Next.js, Prisma y SQLite, incluyendo los modelos de base de datos: usuario, categoría, gastos y presupuestos.
Tip: Siempre menciona que es una demo o proyecto simple. De lo contrario la IA puede generar una arquitectura demasiado compleja para empezar.
Paso 2: OCR básico con Tesseract.js
En la primera versión, Claude Code utiliza Tesseract.js, una biblioteca que corre directamente en el navegador y reconoce caracteres en imágenes (OCR). Funciona bien para extraer texto, pero tiene una limitación importante: no puede categorizar el gasto. Solo ve caracteres, no entiende el contexto.
Por eso damos un paso más y la reemplazamos por la API de OpenAI.
Paso 3: Integrar OpenAI Vision (GPT-4o)
Le pedimos a Claude Code que cambie Tesseract.js por la API de OpenAI para hacer tanto el OCR como la categorización de gastos.
El funcionamiento es sencillo: se sube la imagen al modelo GPT-4o, que es capaz de entender imágenes, y se le pide que devuelva un JSON con esta estructura:
{
"ocr_text": "Texto completo extraído del recibo",
"amount": 15.70,
"description": "Compra en QuickStock Market",
"category": "Alimentos",
"date": "2025-09-30"
}
Si no puede extraer algún campo, devuelve null. La app entonces usa esa información para pre-rellenar el formulario de registro de gasto.
Obtener la API Key de OpenAI
- Ve a platform.openai.com
- Inicia sesión en Plataforma API (no en ChatGPT)
- Ve a la sección API Keys y crea una nueva clave
- Copia la clave y agrégala como variable de entorno en tu proyecto:
OPENAI_API_KEY=sk-...
Importante: Nunca compartas tu API Key ni la subas a GitHub. Con $5 en créditos tienes más que suficiente para desarrollar y probar la aplicación completa.
Paso 4: Alojar imágenes con Cloudinary
Para guardar las fotos de las facturas necesitamos un servicio externo. Cloudinary ofrece un plan gratuito que es perfecto para proyectos en desarrollo o demos.
Configuración
- Créate una cuenta en cloudinary.com (no pide tarjeta)
- Obtén tus credenciales desde el dashboard
- Agrega las variables de entorno:
CLOUDINARY_CLOUD_NAME=tu_cloud_name
CLOUDINARY_API_KEY=tu_api_key
CLOUDINARY_API_SECRET=tu_api_secret
Con esto, cada vez que el usuario guarda un gasto, la imagen se sube a Cloudinary y se guarda la URL en la base de datos. Así los archivos están separados del servidor y disponibles siempre.
Paso 5: Categorías dinámicas
Por defecto, la IA categoriza los gastos usando una lista de categorías hardcodeadas en el código. Lo ideal es que el usuario pueda crear sus propias categorías desde la app.
Le pedimos a Claude Code que:
- Cree una página de administración de categorías (
/categories) - Actualice la ruta de OCR para que obtenga las categorías dinámicamente desde la base de datos
Al crear categorías con tags descriptivos (por ejemplo, "alimentos" con tags como "supermercado, frutas, bebidas"), el modelo de IA puede hacer un match más preciso al categorizar una factura nueva.
Tip para optimizar: Concatenar todas las categorías en el prompt consume tokens. En versiones más avanzadas puedes hacer una búsqueda semántica previa para pasar solo las categorías más relevantes.
Paso 6: Migrar de SQLite a PostgreSQL
SQLite es perfecto para desarrollo local porque no necesita instalación, pero para producción necesitamos una base de datos en red. Le pedimos a Claude Code que cambie el proveedor en Prisma de sqlite a postgresql.
El schema.prisma queda así:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
Paso 7: Subir el proyecto a GitHub
Instalamos GitHub CLI para que Claude Code pueda subir el proyecto directamente desde la terminal:
# En Windows con Winget
winget install --id GitHub.cli
# Autenticarse
gh auth login
Una vez autenticado, le pedimos a Claude Code:
Crea un repositorio público llamado expense-tracker y sube el proyecto
Claude crea el repo, hace el commit inicial y hace el push automáticamente. El proyecto queda disponible en GitHub listo para el deploy.
Nota: Cuando Claude Code hace un commit, se añade como coautor. Si no quieres que aparezca, puedes indicarle que no se incluya como coautor.
Paso 8: Deploy en Seenode
Seenode es una plataforma que permite desplegar tanto el frontend como la base de datos de forma sencilla.
Base de datos
- Ve a la sección Database y crea una nueva base de datos PostgreSQL
- Copia la URI de conexión y agrégala como variable de entorno:
DATABASE_URL=postgresql://usuario:contraseña@host:5432/nombre_db
Frontend
- Ve a Web Service y conecta tu cuenta de GitHub
- Selecciona el repositorio
expense-tracker - Seenode detecta automáticamente que es un proyecto Next.js y configura los comandos de build:
- Build command:
npm run build - Start command:
npm start
- Build command:
- Agrega todas las variables de entorno (OpenAI, Cloudinary, DATABASE_URL)
- Dale en Crear instancia
En pocos minutos tendrás una URL de producción funcional.
Importante: Asegúrate de que tu archivo
.envesté en el.gitignore. Las variables de entorno solo se configuran en la plataforma de deploy, nunca se suben al repositorio.
Resultado final
Al terminar el tutorial tendrás una aplicación full stack completamente funcional y desplegada que:
- Permite registrar usuarios con autenticación
- Escanea facturas con IA y extrae datos automáticamente
- Categoriza los gastos según las categorías que el usuario define
- Guarda las imágenes en Cloudinary
- Muestra un dashboard con resumen de gastos y gráficos
- Soporta modo oscuro
- Está desplegada con una URL pública en producción
Recursos
| Recurso | Enlace |
|---|---|
| Código fuente | GitHub |
| OpenAI Platform | platform.openai.com |
| Cloudinary | cloudinary.com |
| Seenode | seenode.com |
| GitHub CLI | cli.github.com |
| Prisma | prisma.io |
Conclusión
Este proyecto demuestra cómo con las herramientas de IA disponibles hoy es posible construir aplicaciones con funcionalidades que antes eran complejas de implementar. Integrar reconocimiento de imágenes, categorización automática y deploy en producción es ahora accesible para cualquier desarrollador.
A partir de aquí puedes seguir extendiendo la app: agregar envíos de notificaciones, reportes exportables, soporte multiusuario con categorías por cuenta, o integraciones con otros servicios financieros.