Un sistema completo de gestión de inventario construido con Express.js, TypeScript, Prisma ORM y PostgreSQL. Incluye autenticación JWT, roles de usuario y un CRUD completo para inventarios y artículos.
- 🔐 Autenticación JWT: Sistema de login/registro con tokens JWT
- 👥 Roles de Usuario: ADMIN, MANAGER, USER con diferentes permisos
- 📦 Gestión de Inventarios: CRUD completo para inventarios
- 📋 Gestión de Artículos: CRUD completo para artículos con control de stock
- 🔗 Relación Maestro-Esclavo: Inventarios (maestro) → Artículos (esclavos)
- 📊 Estadísticas: Dashboard con métricas de inventario
- 🔍 Filtros Avanzados: Búsqueda, paginación y filtros por categoría, marca, etc.
- 🛡️ Seguridad: Helmet, CORS, validación de datos
- 📝 TypeScript: Código completamente tipado
- 🗄️ PostgreSQL: Base de datos robusta con Prisma ORM
- Backend: Express.js, TypeScript
- Base de Datos: PostgreSQL
- ORM: Prisma
- Autenticación: JWT, bcryptjs
- Seguridad: Helmet, CORS
- Validación: express-validator
- Node.js (v16 o superior)
- PostgreSQL
- npm o yarn
- Clonar el repositorio
git clone <tu-repositorio>
cd node-practices- Instalar dependencias
npm install- Configurar variables de entorno
Crea un archivo
.enven la raíz del proyecto:
# Database
DATABASE_URL="postgresql://postgres:password@localhost:5432/inventory_db"
# JWT
JWT_SECRET="tu_super_secreto_jwt_muy_seguro_2024"
JWT_EXPIRES_IN="24h"
# Server
PORT=3000
NODE_ENV=development- Configurar la base de datos
# Generar el cliente de Prisma
npm run prisma:generate
# Crear las migraciones y aplicar a la base de datos
npm run prisma:migrate
# Poblar la base de datos con datos de ejemplo
npm run prisma:seed- Iniciar el servidor
# Modo desarrollo
npm run dev
# Modo producción
npm run build
npm startid: Identificador únicoemail: Email único del usuariopassword: Contraseña encriptadaname: Nombre del usuariorole: Rol (ADMIN, MANAGER, USER)createdAt,updatedAt: Timestamps
id: Identificador úniconame: Nombre del inventariodescription: Descripción opcionallocation: Ubicación físicastatus: Estado (ACTIVE, INACTIVE, MAINTENANCE, ARCHIVED)userId: Propietario del inventariocreatedAt,updatedAt: Timestamps
id: Identificador úniconame: Nombre del artículosku: Código SKU únicobarcode: Código de barras opcionalcategory: Categoría del artículobrand,model: Marca y modelounit: Unidad de medida (PIEZA, CAJA, etc.)price,cost: Precio de venta y costostock,minStock,maxStock: Control de inventarioweight,dimensions: Características físicascolor,material: Características adicionalessupplier,supplierCode: Información del proveedornotes: Notas adicionalesstatus: Estado (ACTIVE, INACTIVE, DISCONTINUED, OUT_OF_STOCK)inventoryId: Inventario al que pertenececreatedAt,updatedAt: Timestamps
- ADMIN: Acceso completo a todos los recursos
- MANAGER: Puede gestionar inventarios y artículos
- USER: Solo puede ver y gestionar sus propios inventarios
# Registrar usuario
POST /api/auth/register
{
"email": "user@example.com",
"password": "password123",
"name": "Usuario Ejemplo",
"role": "USER"
}
# Iniciar sesión
POST /api/auth/login
{
"email": "user@example.com",
"password": "password123"
}
# Obtener perfil
GET /api/auth/profile
Authorization: Bearer <token>
# Cambiar contraseña
PUT /api/auth/change-password
Authorization: Bearer <token>
{
"currentPassword": "password123",
"newPassword": "newpassword123"
}# Crear inventario
POST /api/inventories
Authorization: Bearer <token>
{
"name": "Almacén Principal",
"description": "Almacén principal de la empresa",
"location": "Edificio A, Nivel 1",
"status": "ACTIVE"
}
# Obtener inventarios (con filtros)
GET /api/inventories?page=1&limit=10&status=ACTIVE&search=almacén
# Obtener inventario por ID
GET /api/inventories/:id
# Actualizar inventario
PUT /api/inventories/:id
Authorization: Bearer <token>
{
"name": "Almacén Actualizado",
"description": "Nueva descripción"
}
# Eliminar inventario
DELETE /api/inventories/:id
Authorization: Bearer <token>
# Obtener estadísticas
GET /api/inventories/stats
Authorization: Bearer <token># Crear artículo
POST /api/articles
Authorization: Bearer <token>
{
"name": "Laptop Dell XPS 13",
"description": "Laptop de alta gama",
"sku": "LAP-DELL-XPS13-001",
"category": "Electrónicos",
"brand": "Dell",
"model": "XPS 13",
"price": 1299.99,
"cost": 1100.00,
"stock": 15,
"minStock": 5,
"maxStock": 50,
"inventoryId": "inventory_id_here"
}
# Obtener artículos (con filtros)
GET /api/articles?page=1&limit=10&category=Electrónicos&brand=Dell&inStock=true
# Obtener artículo por ID
GET /api/articles/:id
# Actualizar artículo
PUT /api/articles/:id
Authorization: Bearer <token>
{
"price": 1199.99,
"stock": 20
}
# Eliminar artículo
DELETE /api/articles/:id
Authorization: Bearer <token>
# Actualizar stock
PATCH /api/articles/:id/stock
Authorization: Bearer <token>
{
"quantity": 5,
"operation": "add" // "add", "subtract", "set"
}
# Obtener estadísticas
GET /api/articles/stats
Authorization: Bearer <token>page: Número de páginalimit: Elementos por páginastatus: Filtrar por estadosearch: Búsqueda en nombre, descripción y ubicación
page: Número de páginalimit: Elementos por páginacategory: Filtrar por categoríabrand: Filtrar por marcastatus: Filtrar por estadoinventoryId: Filtrar por inventariosearch: Búsqueda en nombre, descripción, SKU y código de barrasminPrice,maxPrice: Rango de preciosinStock: Solo artículos con stock > 0
El sistema incluye datos de ejemplo con:
- admin@inventory.com (ADMIN) - password: password123
- manager@inventory.com (MANAGER) - password: password123
- user@inventory.com (USER) - password: password123
- Almacén Principal (ADMIN)
- Inventario de Oficina (MANAGER)
- Inventario de Mantenimiento (USER)
- Laptops, monitores, teclados (Electrónicos)
- Papel, bolígrafos (Papelería)
- Herramientas, taladros (Herramientas)
# Desarrollo
npm run dev # Iniciar servidor en modo desarrollo
# Producción
npm run build # Compilar TypeScript
npm start # Iniciar servidor en modo producción
# Base de datos
npm run prisma:generate # Generar cliente Prisma
npm run prisma:migrate # Ejecutar migraciones
npm run prisma:seed # Poblar base de datos
npm run prisma:studio # Abrir Prisma Studiosrc/
├── controllers/ # Controladores de la API
├── middleware/ # Middlewares (auth, validación)
├── routes/ # Definición de rutas
├── types/ # Tipos TypeScript
└── index.ts # Archivo principal
DATABASE_URL="postgresql://usuario:password@localhost:5432/nombre_db"
JWT_SECRET="tu_secreto_jwt"
JWT_EXPIRES_IN="24h"
PORT=3000
NODE_ENV=developmentPara probar la API, puedes usar herramientas como:
- Postman
- Insomnia
- curl
# Login
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@inventory.com","password":"password123"}'
# Obtener inventarios (con token)
curl -X GET http://localhost:3000/api/inventories \
-H "Authorization: Bearer <token>"- Node.js 16+
- PostgreSQL 12+
- Variables de entorno configuradas
- Base de datos migrada y poblada
- Configurar variables de entorno de producción
- Ejecutar
npm run build - Ejecutar
npm run prisma:migrate - Iniciar con
npm start
Este proyecto está bajo la Licencia ISC.
- Fork el proyecto
- Crea una rama para tu feature (
git checkout -b feature/AmazingFeature) - Commit tus cambios (
git commit -m 'Add some AmazingFeature') - Push a la rama (
git push origin feature/AmazingFeature) - Abre un Pull Request
Si tienes alguna pregunta o problema, por favor abre un issue en el repositorio.