Sistema completo de gestión para heladerías con punto de venta web, carrito anónimo, checkout simulado y dashboard administrativo en tiempo real. Arquitectura full-stack moderna con seguridad reforzada y actualización automática de inventario.
- Catálogo interactivo con categorías, búsqueda reactiva y filtros en tiempo real
- Carrito anónimo persistente con localStorage (sin registro de usuario)
- Checkout simulado con múltiples métodos de pago (QR, tarjeta, efectivo, transferencia)
- Actualización automática de stock cada 30 segundos mediante polling
- UI/UX moderna con Tailwind CSS, animaciones suaves y diseño responsive
- Panel de control en tiempo real con métricas actualizadas automáticamente cada 5 segundos
- Gestión de productos con actualización automática de stock al realizar ventas
- Sistema de ventas manuales para atención en caja física
- Reportes exportables (CSV/PDF) con filtros por fecha y método de pago
- Gestión de empleados y categorías de productos
- Autenticación JWT con doble cookie (access + refresh tokens, httpOnly)
- Protección CSRF con doble envío de token en cookies y headers
- Rate limiting global y específico en endpoints críticos
- Helmet.js con CSP, HSTS, y headers de seguridad
- Actualización automática de inventario con descuento de stock transaccional
- Stock sincronizado: Cada venta descuenta automáticamente del inventario
- Polling inteligente:
- Frontend público: 30s
- Dashboard admin: 5s
- Ventas: 5s
- Invalidación de queries en React Query al completar transacciones
- NestJS 10 - Framework Node.js progresivo
- TypeORM - ORM con soporte para PostgreSQL
- PostgreSQL 17 - Base de datos relacional
- JWT - Autenticación con tokens
- bcrypt - Hash de contraseñas (salt 10)
- Helmet - Seguridad HTTP
- React 19 - Biblioteca UI moderna
- Vite 6 - Build tool ultrarrápido
- TanStack Query (React Query) - Gestión de estado servidor
- Tailwind CSS - Framework CSS utility-first
- TypeScript 5 - Tipado estático
- React Router 7 - Navegación SPA
- Docker + Docker Compose - Contenerización
- Nginx - Servidor web y proxy inverso
- Multi-stage builds - Optimización de imágenes Docker
heladeria-digital-suite/
├── backend/ # API REST con NestJS
│ ├── src/
│ │ ├── auth/ # Sistema de autenticación JWT
│ │ ├── carritos/ # Gestión de carritos anónimos
│ │ ├── carrito-items/ # Items individuales del carrito
│ │ ├── categorias/ # Categorías de productos
│ │ ├── productos/ # CRUD de productos con stock
│ │ ├── ventas/ # Registro y gestión de ventas
│ │ ├── detalles-ventas/ # Detalles de cada venta
│ │ ├── pagos-simulados/ # Simulación de pagos
│ │ ├── empleados/ # Gestión de usuarios admin
│ │ ├── reportes/ # Reportes y estadísticas
│ │ ├── seed/ # Semilla de datos inicial
│ │ ├── common/ # Middlewares, filtros, utils
│ │ └── config/ # Validación de variables de entorno
│ ├── .env.local # Configuración desarrollo local
│ ├── .env.pruebas # Configuración Docker local
│ ├── .env.produccion # Configuración producción
│ ├── Dockerfile # Build multi-etapa optimizado
│ ├── docker-entrypoint.sh # Script de inicio automático
│
│
├── frontend/ # SPA React + Vite
│ ├── src/
│ │ ├── components/ # Componentes reutilizables
│ │ │ ├── Cart/ # Sistema de carrito
│ │ │ ├── dashboard/ # Componentes del admin
│ │ │ └── public/ # Componentes públicos
│ │ ├── context/ # Context API (Auth, Cart)
│ │ ├── hooks/ # Custom hooks con React Query
│ │ ├── models/ # Interfaces TypeScript
│ │ ├── pages/ # Páginas principales
│ │ ├── routes/ # Configuración de rutas
│ │ └── services/ # Servicios API
│ ├── Dockerfile # Build Nginx + React
│ └── nginx.conf # Configuración Nginx
│
├── docker-compose.yml # Orquestación desarrollo
├── docker-compose.prod.yml # Orquestación producción
└── README.md # Este archivo
- Node.js 20+ y npm 10+ (para desarrollo local)
- Docker y Docker Compose (recomendado)
- PostgreSQL 17 (si no usas Docker)
# 1. Clonar el repositorio
git clone <tu-repo>
cd heladeria-digital-suite
# 2. Levantar toda la infraestructura
docker-compose up -d
# 3. El admin se crea automáticamente (seed habilitado en .env.pruebas)
# Acceder a:
# - Frontend: http://localhost
# - Backend: http://localhost:3000/api
# - Login: http://localhost/login
# Usuario: admin@heladeria.com
# Password: admin123
# 4. Ver logs
docker-compose logs -f backend
# 5. Detener servicios
docker-compose downcd backend
# 1. Instalar dependencias
npm install
# 2. Configurar variables de entorno
cp .env.local .env
# Edita .env con tus credenciales de PostgreSQL
# 3. Habilitar seed para crear admin (primera vez)
# En .env, cambia: SEED_ON_BOOT=true
# 4. Iniciar servidor
npm run start:dev
# El backend corre en http://localhost:3000cd frontend
# 1. Instalar dependencias
npm install
# 2. Configurar variables de entorno
echo "VITE_API_URL=http://localhost:3000/api" > .env.local
# 3. Iniciar servidor de desarrollo
npm run dev
# El frontend corre en http://localhost:5173El sistema incluye un seed automático que crea el usuario admin:
-
Configura el seed en el archivo
.envcorrespondiente:SEED_ON_BOOT=true SEED_ADMIN_NAME=Administrador SEED_ADMIN_EMAIL=admin@heladeria.com SEED_ADMIN_PASSWORD=admin123
-
Inicia la aplicación: El admin se crea automáticamente
-
Inicia sesión en:
http://localhost/loginohttp://localhost:5173/login -
(Opcional) Desactiva el seed por seguridad:
SEED_ON_BOOT=false
📖 Para más detalles: Lee backend/SEED_INSTRUCTIONS.md
⚠️ IMPORTANTE: En producción, cambia las credenciales antes del deploy y desactiva el seed después del primer inicio.
.env.local- Desarrollo local (sin Docker).env.pruebas- Docker Compose local.env.produccion- Deployment en servidor
# Servidor
PORT=3000
NODE_ENV=development|production
HOST=0.0.0.0
# Base de datos
DB_HOST=localhost # 'db' en Docker
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=tu_password
DB_NAME=heladeria_db
DB_SYNCHRONIZE=true # false en producción
DB_LOGGING=true # false en producción
# CORS
FRONTEND_URL=http://localhost:5173
# JWT (genera secretos seguros en producción)
JWT_ACCESS_SECRET=tu_secret_64_caracteres_minimo
JWT_REFRESH_SECRET=otro_secret_64_caracteres
# Seguridad
COOKIE_SECURE=false # true en producción (HTTPS)
COOKIE_SAMESITE=lax # strict en producción
CSRF_ENABLED=true
THROTTLE_TTL=60000
THROTTLE_LIMIT=100
# Seed (creación automática de admin)
SEED_ON_BOOT=false # true para primera vez
SEED_ADMIN_NAME=Administrador
SEED_ADMIN_EMAIL=admin@heladeria.com
SEED_ADMIN_PASSWORD=admin123 # Cambiar en producción# API Backend
VITE_API_URL=http://localhost:3000/api
# Nombre de la aplicación
VITE_APP_NAME="Heladería Digital"# Ejecuta en tu terminal:
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
# Copia el resultado para JWT_ACCESS_SECRET
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
# Copia el resultado para JWT_REFRESH_SECRET- Access Token: 15 minutos,
httpOnly,secure(en producción) - Refresh Token: 7 días,
httpOnly,secure - Renovación automática: Transparente en el frontend con React Query
- Doble envío: Cookie
csrf_token+ HeaderX-CSRF-Token - Validación: Middleware en todas las mutaciones (POST, PUT, DELETE, PATCH)
- Rotación: Nuevo token en cada login/refresh
- CSP (Content Security Policy): Políticas estrictas
- HSTS: HTTP Strict Transport Security (producción)
- X-Frame-Options: Prevención de clickjacking
- Deshabilitación de X-Powered-By
- Global: 100 peticiones por minuto
- Login: 5 intentos por minuto por IP
- Refresh: 10 peticiones por minuto por IP
- bcrypt con salt factor 10
- Prevención de rehashing: Validación en hooks
@BeforeUpdate - No se devuelven passwords en ningún endpoint
- Explorar catálogo: Navega categorías, busca productos, ve detalles
- Agregar al carrito: Sin necesidad de registro (cliente temporal UUID)
- Checkout: Elige método de pago (QR/tarjeta/efectivo/transferencia)
- Confirmación: Se registra la venta y se descuenta el stock automáticamente
- Actualización: El inventario se refleja en tiempo real (30s polling)
- Login seguro: Autenticación JWT con cookies httpOnly
- Dashboard: Métricas en tiempo real (actualización cada 5s)
- Gestión de productos:
- CRUD completo
- Control de stock actualizado automáticamente
- Ver ventas en tiempo real
- Ventas manuales: Registro desde caja física con descuento de stock transaccional
- Reportes: Exportar ventas diarias en CSV/PDF con filtros avanzados
- Gestión de empleados: Crear/editar usuarios del sistema
npm run start:dev # Desarrollo con hot-reload
npm run build # Compilar a dist/
npm run start:prod # Producción desde dist/
npm run lint # Lint con ESLint
npm run test # Tests unitarios con Jest
npm run test:e2e # Tests end-to-endnpm run dev # Vite dev server (http://localhost:5173)
npm run build # Build de producción
npm run preview # Preview del build
npm run lint # Lint con ESLint + TypeScript# Desarrollo local
docker-compose up -d # Levantar servicios
docker-compose logs -f backend # Ver logs del backend
docker-compose logs -f frontend # Ver logs del frontend
docker-compose restart backend # Reiniciar backend (recargar .env)
docker-compose down # Detener servicios
docker-compose down -v # Detener y borrar volúmenes (limpia BD)
# Producción
docker-compose -f docker-compose.prod.yml up -d
docker-compose -f docker-compose.prod.yml logs -f
docker-compose -f docker-compose.prod.yml downPOST /api/auth/login # Login con rate limiting
POST /api/auth/refresh # Renovar tokens (requiere CSRF)
POST /api/auth/logout # Cerrar sesión
GET /api/auth/me # Perfil del usuario actual
GET /api/auth/csrf # Obtener token CSRF
GET /api/categorias # Listar categorías
GET /api/productos # Listar productos con stock
GET /api/productos/:id # Detalle de producto
POST /api/carritos # Crear carrito anónimo
GET /api/carritos/:id # Obtener carrito
POST /api/carritos/:id/items # Agregar item
PATCH /api/carrito-items/:id # Actualizar cantidad
DELETE /api/carrito-items/:id # Eliminar item
POST /api/carritos/:id/checkout # Finalizar compra (descuenta stock)
GET /api/productos # Gestión de inventario
POST /api/productos # Crear producto (requiere CSRF)
PATCH /api/productos/:id # Actualizar producto
DELETE /api/productos/:id # Eliminar producto
GET /api/ventas # Listar ventas (actualización cada 5s)
POST /api/ventas # Crear venta manual
GET /api/ventas/:id # Detalle de venta
GET /api/reportes/calendario # Calendario de ventas
GET /api/reportes/dia # Reporte diario con exportación
-
Edita
backend/.env.produccion:# Cambiar TODAS estas variables: DB_PASSWORD=una_password_muy_segura JWT_ACCESS_SECRET=genera_un_secret_aleatorio_64_chars JWT_REFRESH_SECRET=genera_otro_secret_aleatorio_64_chars FRONTEND_URL=https://tudominio.com SEED_ADMIN_EMAIL=admin@tudominio.com SEED_ADMIN_PASSWORD=PasswordSegura123! # Primera vez: true, después: false SEED_ON_BOOT=true # Producción NODE_ENV=production COOKIE_SECURE=true COOKIE_SAMESITE=strict DB_SYNCHRONIZE=false
-
SSL/TLS: Configura certificados en
/etc/letsencrypt/(Let's Encrypt)
# 1. En el servidor, clona el repositorio
git clone <tu-repo>
cd heladeria-digital-suite
# 2. Edita .env.produccion con tus valores reales
# 3. Levanta con Docker Compose
docker-compose -f docker-compose.prod.yml up -d
# 4. Verifica que el admin se creó
docker-compose -f docker-compose.prod.yml logs backend | grep "ADMIN"
# 5. Accede y cambia la contraseña del admin
# 6. IMPORTANTE: Desactiva el seed
nano backend/.env.produccion
# Cambia: SEED_ON_BOOT=false
docker-compose -f docker-compose.prod.yml restart backend# Ver logs
docker-compose -f docker-compose.prod.yml logs -f
# Backup de base de datos
docker exec -t postgres pg_dump -U postgres heladeria_db > backup_$(date +%Y%m%d).sql
# Restaurar backup
cat backup_20241212.sql | docker exec -i postgres psql -U postgres heladeria_db
# Actualizar código
git pull
docker-compose -f docker-compose.prod.yml up -d --buildEl sistema usa cookies httpOnly y tokens CSRF, por lo que es más fácil usar el frontend. Pero si necesitas testear con Postman:
-
Obtener CSRF Token:
GET http://localhost:3000/api/auth/csrfGuarda el
csrfTokende la respuesta. -
Login:
POST http://localhost:3000/api/auth/login Headers: Content-Type: application/json X-CSRF-Token: <token-del-paso-1> Body: { "email": "admin@heladeria.com", "password": "admin123" }Postman guardará las cookies automáticamente.
-
Endpoints protegidos: Incluye siempre
X-CSRF-Tokenen el header para POST/PUT/DELETE/PATCH.
💡 Recomendación: Usa el frontend para operaciones normales. Postman es útil solo para debugging de la API.
- Fork el proyecto
- Crea una rama feature (
git checkout -b feature/nueva-funcionalidad) - Commit tus cambios (
git commit -am 'Agrega nueva funcionalidad') - Push a la rama (
git push origin feature/nueva-funcionalidad) - Abre un Pull Request
Este proyecto está bajo la licencia MIT. Ver archivo LICENSE para más detalles.
Desarrollado por eld4vd
Solución: Usa el seed para crear el primer admin. El sistema usa cookies httpOnly que Postman no maneja bien.
Verifica:
SEED_ON_BOOT=trueen el.envcorrecto- La base de datos está vacía (no hay empleados)
- Los logs del backend:
docker-compose logs backend
Solución:
- Obtén un nuevo token con
GET /api/auth/csrf - Incluye el header
X-CSRF-Tokenen todas las mutaciones - Asegúrate de que Postman maneje cookies automáticamente
Verifica:
- React Query está configurado con
refetchInterval: 5000 - El backend descuenta stock en
carritos.service.ts - Las queries se invalidan después del checkout