ClientFlow es una aplicación full-stack tipo mini CRM creada para recibir, organizar y administrar leads provenientes de sitios web, landing pages, campañas digitales o integraciones externas.
El proyecto fue desarrollado como aplicación de portfolio para demostrar conocimientos prácticos en backend, frontend, autenticación, bases de datos relacionales, deploy, automatización y consumo de APIs desde una interfaz moderna.
- Frontend: https://clientflow-crm-roan.vercel.app
- Backend API: https://clientflow-api-n9gh.onrender.com
- Health check: https://clientflow-api-n9gh.onrender.com/health
Nota: el backend está desplegado en Render Free. Si la API estuvo inactiva durante un tiempo, puede tardar algunos segundos en responder en el primer acceso.
Email: usuario@test.com
Password: contra123Proyecto funcional y desplegado.
Actualmente incluye:
- Backend deployado en Render.
- Frontend deployado en Vercel.
- Base de datos PostgreSQL en Neon.
- Seed demo con datos ficticios.
- Reset automático de la base demo cada 4 días usando GitHub Actions.
- Interfaz responsive conectada al backend.
- README preparado para portfolio, uso local y deploy.
- Descripción del proyecto
- Qué problema resuelve
- Funcionalidades principales
- Tecnologías utilizadas
- Arquitectura general
- Modelo de datos
- Endpoints principales
- Instalación local
- Variables de entorno
- Seed de datos demo
- Reset automático de la demo
- Scripts disponibles
- Validaciones-y-manejo-de-errores
- Seguridad
- Objetivo de portfolio
- Autor
ClientFlow simula una plataforma CRM sencilla donde una empresa puede recibir consultas comerciales y gestionarlas desde un panel privado.
El flujo principal de la aplicación es:
Formulario web, landing page, campaña o integración externa
↓
API REST
↓
Base de datos PostgreSQL
↓
Panel privado
↓
Gestión comercial del leadEn esta demo, el formulario público sirve para simular la recepción de leads desde distintos canales como sitio web, landing pages, anuncios, Instagram o referidos. Para facilitar la prueba del proyecto, el origen del lead puede seleccionarse manualmente desde el formulario.
Desde el panel interno se pueden ver leads, filtrarlos, cambiar su estado, asociarlos a clientes, agregar notas internas y revisar métricas generales en un dashboard.
La aplicación no fue pensada como producto comercial final, sino como un proyecto completo para demostrar habilidades full-stack en un caso de uso realista.
Muchas empresas reciben consultas desde distintos canales: sitios web, formularios, campañas, redes sociales o referidos. Si esas consultas quedan dispersas, es difícil darles seguimiento.
ClientFlow centraliza esa información en un flujo simple:
- La empresa recibe un lead desde un formulario web, landing page, campaña publicitaria o integración externa.
- La consulta se guarda como lead.
- Un usuario interno inicia sesión en el panel.
- El lead se puede clasificar por estado.
- El lead se puede asociar a un cliente.
- Se pueden agregar notas internas.
- El dashboard muestra estadísticas generales.
- Registro de usuario mediante API.
- Login con email y contraseña.
- Contraseñas hasheadas con bcryptjs.
- Autenticación con JWT.
- Rutas privadas protegidas con middleware.
- Persistencia de sesión en el frontend usando almacenamiento local.
- Crear leads desde formulario público.
- Listar leads desde el panel privado.
- Buscar leads por nombre, email, mensaje u origen.
- Filtrar leads por estado.
- Filtrar leads por cliente asociado.
- Ordenar leads por fecha, nombre, email o estado.
- Paginación.
- Ver detalle de un lead.
- Cambiar estado de un lead.
- Asociar o desasociar un lead con un cliente.
- Borrar leads.
Los estados internos de la API son:
new
contacted
quoted
closed
lostEn el frontend se muestran en español como:
Nuevo
Contactado
Presupuestado
Cerrado
Perdido- Crear clientes.
- Listar clientes.
- Ver detalle de un cliente.
- Editar datos de un cliente.
- Borrar clientes.
- Ver leads asociados a un cliente.
- Crear notas internas en un lead.
- Listar notas asociadas a un lead.
- Borrar notas.
- Asociar notas al usuario autenticado.
- Total de leads.
- Total de clientes.
- Total de notas.
- Leads creados hoy.
- Leads creados este mes.
- Leads por estado.
- Leads por origen.
- Leads recientes.
- Tasa de conversión.
- Tasa de pérdida.
- Login.
- Dashboard.
- Página de leads.
- Página de detalle de lead.
- Página de clientes.
- Página de detalle de cliente.
- Formulario público.
- Diseño responsive.
- Detección visual de conexión con la API.
- Mensajes de error en español.
- Interfaz conectada completamente al backend.
- Node.js
- Express
- TypeScript
- Prisma ORM
- PostgreSQL
- Neon
- Zod
- JWT con jose
- bcryptjs
- dotenv
- CORS
- React
- Vite
- TypeScript
- React Router
- CSS responsive
- Fetch API
- Context API para autenticación
- Render para backend.
- Vercel para frontend.
- Neon para PostgreSQL.
- GitHub Actions para reset automático de datos demo.
- Git / GitHub.
- npm.
- PowerShell para pruebas manuales.
El proyecto está organizado como una aplicación full-stack en un mismo repositorio.
clientflow-crm/
src/ Backend Express + TypeScript
prisma/ Schema, migraciones y seed de datos demo
web/ Frontend React + Vite
.github/workflows/ Automatización para reset de datos demoEn desarrollo local:
Frontend React + Vite
↓
http://localhost:3000
↓
Backend Express + TypeScript
↓
PostgreSQLEn producción:
Frontend en Vercel
↓
Backend en Render
↓
PostgreSQL en NeonEl sistema trabaja con cuatro entidades principales.
Representa un usuario administrador del CRM.
Campos principales:
id
name
email
password
createdAt
updatedAtRepresenta una consulta o contacto recibido desde un formulario, campaña o integración externa.
Campos principales:
id
name
email
phone
message
source
status
clientId
createdAt
updatedAtRepresenta un cliente o empresa asociada a uno o más leads.
Campos principales:
id
name
email
phone
company
createdAt
updatedAtRepresenta una nota interna asociada a un lead.
Campos principales:
id
content
leadId
userId
createdAt
updatedAtGET /healthVerifica si la API está funcionando.
POST /auth/register
POST /auth/login
GET /auth/meGET /auth/me requiere token JWT.
GET /leads
POST /leads/public
GET /leads/:id
PATCH /leads/:id/status
PATCH /leads/:id/client
DELETE /leads/:idLa mayoría de rutas de leads son privadas, excepto:
POST /leads/publicEjemplos de filtros:
GET /leads?page=1&limit=5
GET /leads?status=contacted
GET /leads?search=landing
GET /leads?clientId=1
GET /leads?sortBy=name&sortOrder=ascGET /clients
POST /clients
GET /clients/:id
PUT /clients/:id
DELETE /clients/:idTodas las rutas de clientes requieren autenticación.
GET /leads/:id/notes
POST /leads/:id/notes
DELETE /notes/:idTodas las rutas de notas requieren autenticación.
GET /dashboard/statsDevuelve métricas generales del CRM. Requiere autenticación.
Antes de empezar, necesitás tener instalado:
- Node.js.
- npm.
- Git.
- Una base PostgreSQL.
- Opcional: cuenta en Neon para usar PostgreSQL en la nube.
Cloná el repositorio:
git clone https://github.com/shodryi/clientflow-crm
cd clientflow-crmInstalá dependencias del backend:
npm installInstalá dependencias del frontend:
cd web
npm install
cd ..Creá un archivo .env en la raíz del proyecto usando como referencia .env.example:
PORT=3000
DATABASE_URL="postgresql://PASSWORD@HOST-POOLER.neon.tech/DATABASE?sslmode=require"
DIRECT_DATABASE_URL="postgresql://PASSWORD@HOST.neon.tech/DATABASE?sslmode=require"
JWT_SECRET="change-this-secret-key-with-at-least-32-characters"Notas:
DATABASE_URLse usa para la conexión principal de la aplicación.DIRECT_DATABASE_URLse usa para operaciones directas como migraciones o tareas de mantenimiento.JWT_SECRETdebe tener al menos 32 caracteres.
Creá un archivo .env dentro de web/ usando como referencia web/.env.example:
VITE_API_URL=http://localhost:3000Para producción en Vercel, esta variable apunta al backend deployado:
VITE_API_URL=https://clientflow-api-n9gh.onrender.comDesde la raíz del proyecto:
npx prisma generateAplicá migraciones en una base de desarrollo:
npx prisma migrate devCargá datos demo:
npx prisma db seedLevantá el servidor:
npm run devLa API debería quedar disponible en:
http://localhost:3000Probá el health check:
http://localhost:3000/healthEn otra terminal:
cd web
npm run devEl frontend debería quedar disponible en:
http://localhost:5173El proyecto incluye un archivo de seed en:
prisma/seed.tsEste seed crea datos ficticios para probar la aplicación:
- Usuario demo.
- Clientes.
- Leads.
- Notas.
- Relaciones entre leads y clientes.
- Fechas distribuidas para que el dashboard se vea más realista.
Ejecutá la seed con:
npx prisma db seedLuego podés iniciar sesión con:
Email: usuario@test.com
Password: contra123La demo pública usa una base de datos PostgreSQL en Neon.
Este proyecto incluye un workflow de GitHub Actions que resetea los datos demo automáticamente cada 4 días.
Desde la raíz del proyecto:
npm run devCompila TypeScript a JavaScript en dist/.
npm run startEjecuta la versión compilada.
npx prisma generateGenera Prisma Client.
npx prisma migrate devCrea o aplica migraciones en desarrollo.
npx prisma migrate deployAplica migraciones pendientes en producción o deploy.
npx prisma db seedEjecutar la seed demo.
Desde la carpeta web/:
npm run devLevanta Vite en modo desarrollo.
npm run buildGenera la build de producción del frontend.
npm run previewPrevisualiza la build de producción localmente.
El backend usa Zod para validar:
- body
- params
- query params
Ejemplos de validaciones:
- Email válido.
- Campos obligatorios.
- IDs positivos.
- Estados permitidos.
- Límites de longitud.
- Paginación válida.
- Ordenamiento permitido.
El frontend muestra errores en español y detecta casos como:
- API apagada.
- Login incorrecto.
- Token inválido o expirado.
- Validaciones fallidas.
- Recursos no encontrados.
El proyecto incluye las siguientes medidas de seguridad:
- Contraseñas hasheadas con bcryptjs.
- JWT para rutas privadas.
- Middleware de autenticación.
- Variables sensibles fuera del repositorio.
.env.examplepara documentar configuración sin exponer secretos reales.- Validaciones centralizadas con Zod.
- Manejo controlado de errores.
- Separación entre rutas públicas y privadas.
Este proyecto demuestra:
- Desarrollo backend con Node.js, Express y TypeScript.
- Diseño de API REST.
- Validaciones con Zod.
- Autenticación con JWT.
- Hash de contraseñas.
- Uso de ORM con Prisma.
- Modelado de datos relacionales.
- Uso de PostgreSQL en la nube con Neon.
- Migraciones de base de datos.
- Seed de datos demo.
- Uso de GitHub Actions.
- Manejo de errores centralizado.
- Frontend con React, Vite y TypeScript.
- Consumo de API desde frontend.
- Rutas protegidas.
- Formularios controlados.
- Estado global de autenticación.
- Diseño responsive.
- Deploy de backend en Render.
- Deploy de frontend en Vercel.
- Organización de proyecto full-stack.
Desarrollado por Rodrigo Sanchez.
Proyecto creado como parte de portfolio personal para demostrar habilidades full-stack orientadas a desarrollo web, APIs, bases de datos, autenticación, deploy y frontend moderno.