Skip to content

Emmanu2288/Server

Repository files navigation

🛒 Backend I - E-Commerce Server

Servidor backend moderno para una plataforma de e-commerce construido con Express.js, MongoDB y Socket.io. Este proyecto implementa un sistema completo de gestión de productos y carritos de compra con soporte para tiempo real.


📋 Tabla de Contenidos


✨ Características

Gestión de Productos

  • Crear, leer, actualizar y eliminar productos (CRUD)
  • Paginación, filtrado y ordenamiento
  • Disponibilidad y categorización

Sistema de Carritos

  • Crear carritos de compra
  • Agregar/eliminar productos
  • Actualizar cantidades
  • Limpiar carrito

Real-time con WebSockets

  • Conexión Socket.io para actualizaciones en tiempo real
  • Soporte para múltiples clientes simultáneos

Vistas Dinámicas

  • Renderizado con Handlebars
  • Interfaz responsiva con Bootstrap
  • Múltiples vistas (Home, Productos, Carrito, Real-Time)

Base de Datos

  • MongoDB con Mongoose
  • Schema validación
  • Paginación integrada

📁 Estructura del Proyecto

Server/
├── app.js                          # Entrada principal de la aplicación
├── socket.js                       # Configuración de Socket.io
├── products.json                   # Datos de productos iniciales
├── package.json                    # Dependencias y scripts
│
├── config/                         # Configuración de la aplicación
│   ├── db/
│   │   └── connect.config.js      # Conexión a MongoDB
│   └── models/
│       ├── product.js             # Schema de Productos
│       └── cart.js                # Schema de Carritos
│
├── controllers/                    # Lógica de negocio
│   ├── products.controller.js      # Controlador de productos
│   └── carts.controller.js         # Controlador de carritos
│
├── routes/                         # Definición de rutas
│   ├── products.router.js          # Rutas API de productos
│   ├── carts.router.js             # Rutas API de carritos
│   ├── home.router.js              # Ruta de inicio
│   └── views.router.js             # Rutas de vistas renderizadas
│
├── views/                          # Plantillas Handlebars
│   ├── home.hbs                   # Vista de inicio
│   ├── products.hbs               # Vista de productos
│   ├── cart.hbs                   # Vista del carrito
│   ├── realTimeProducts.hbs       # Vista de productos en tiempo real
│   └── layouts/
│       └── main.hbs               # Layout principal
│
├── public/                         # Archivos estáticos
│   ├── css/
│   │   └── styles.css             # Estilos personalizados
│   └── img/                       # Imágenes del proyecto
│
├── postman/                        # Colecciones de Postman
│   ├── Productos.postman_collection.json
│   └── Carritos.postman_collection.json
│
└── README.md                       # Este archivo

🏗️ Arquitectura del Sistema

Diagrama General de Arquitectura

graph TB
    subgraph Client["🌐 Cliente"]
        Browser["Navegador Web"]
        Postman["Postman/API Client"]
    end

    subgraph Express["🚀 Express Server<br/>port 3000"]
        subgraph Middleware["Middlewares"]
            Parser["JSON Parser"]
            Static["Static Files"]
            IO["Socket.io Injector"]
        end
        
        subgraph Routing["Rutas"]
            API["API Routes"]
            Views["View Routes"]
            Home["Home Route"]
        end
        
        subgraph Controllers["Controladores"]
            ProdCtrl["Products Controller"]
            CartCtrl["Carts Controller"]
        end
        
        subgraph Models["Modelos & Schemas"]
            Product["Product Schema"]
            Cart["Cart Schema"]
        end
    end

    subgraph Database["💾 MongoDB"]
        ProdDB["Colección: products"]
        CartDB["Colección: carts"]
    end

    subgraph RealTime["⚡ WebSockets"]
        SocketIO["Socket.io"]
    end

    subgraph Views["🎨 Vistas Renderizadas"]
        Handlebars["Handlebars/HBS"]
        Bootstrap["Bootstrap CSS"]
    end

    Browser -->|HTTP Requests| API
    Postman -->|API Calls| API
    Browser -->|WebSocket| SocketIO
    API --> Middleware
    Middleware --> Routing
    API --> Controllers
    Views --> Controllers
    Controllers --> Models
    Models --> Database
    SocketIO --> Database
    Routing --> Views
    Views --> Handlebars
    Handlebars --> Bootstrap
    Bootstrap -->|HTML Response| Browser
Loading

Diagrama de Capas

graph TB
    Client["📱 Capa de Presentación<br/>Cliente"]
    Express["🚀 Capa de Aplicación<br/>Express.js"]
    Business["⚙️ Capa de Lógica Negocio<br/>Controllers"]
    Data["💾 Capa de Datos<br/>Models & MongoDB"]
    
    Client -->|Request/Response| Express
    Express -->|Validación| Business
    Business -->|CRUD Ops| Data
    Data -->|Datos| Business
    Business -->|Response| Express
    Express -->|HTML/JSON| Client

    style Client fill:#e1f5ff
    style Express fill:#f3e5f5
    style Business fill:#fff3e0
    style Data fill:#e8f5e9
Loading

🔧 Instalación

Prerrequisitos

  • Node.js v16 o superior
  • MongoDB local o remoto
  • npm o yarn

Pasos de Instalación

  1. Clonar el repositorio

    git clone https://github.com/Emmanu2288/Backend-I.git
    cd "Backend 1/Server"
  2. Instalar dependencias

    npm install
  3. Configurar la base de datos

    • Asegúrate de que MongoDB esté corriendo en localhost:27017
    • Base de datos: ecommerce
    • Si deseas cambiar la conexión, edita config/db/connect.config.js
  4. Ejecutar el servidor

    # Desarrollo (con nodemon)
    npm run dev
    
    # Producción
    npm start
  5. Verificar instalación

    • Accede a http://localhost:3000/home en tu navegador
    • Deberías ver la página de inicio

🚀 Uso

Iniciar el Servidor

Modo Desarrollo (con hot-reload):

npm run dev

Modo Producción:

npm start

Rutas Disponibles

🏠 Vistas (HTML)

Ruta Método Descripción
/home GET Página de inicio con productos
/products GET Listado de productos con paginación
/carts/:cid GET Vista del carrito específico
/realtimeproducts GET Vista en tiempo real de productos

🔌 API REST

Productos:

Método Endpoint Descripción
GET /api/products Obtener todos los productos
GET /api/products/:pid Obtener producto por ID
POST /api/products Crear nuevo producto
PUT /api/products/:pid Actualizar producto
DELETE /api/products/:pid Eliminar producto

Carritos:

Método Endpoint Descripción
POST /api/carts Crear nuevo carrito
GET /api/carts/:cid Obtener carrito con productos
POST /api/carts/:cid/products/:pid Agregar producto al carrito
PUT /api/carts/:cid/products/:pid Actualizar cantidad de producto
DELETE /api/carts/:cid/products/:pid Eliminar producto del carrito
PUT /api/carts/:cid Actualizar todos los productos
DELETE /api/carts/:cid Vaciar carrito

📊 Endpoints API

📦 Productos

GET /api/products

Obtiene lista de productos con paginación, filtrado y ordenamiento.

Parámetros de Query:

  • page (number, default: 1) - Número de página
  • limit (number, default: 10) - Productos por página
  • sort (string: 'asc' | 'desc') - Ordenar por precio
  • query (string) - Filtrar por categoría o 'available'

Ejemplo:

GET /api/products?page=1&limit=10&sort=asc&query=electronics

Respuesta (200):

{
  "status": "success",
  "payload": [
    {
      "_id": "507f1f77bcf86cd799439011",
      "name": "Laptop",
      "price": 999.99,
      "category": "electronics",
      "available": true,
      "createdAt": "2024-03-19T10:30:00.000Z",
      "updatedAt": "2024-03-19T10:30:00.000Z"
    }
  ],
  "totalPages": 5,
  "page": 1,
  "hasPrevPage": false,
  "hasNextPage": true,
  "prevLink": null,
  "nextLink": "/api/products?page=2"
}

GET /api/products/:pid

Obtiene un producto específico por su ID.

Ejemplo:

GET /api/products/507f1f77bcf86cd799439011

Respuesta (200):

{
  "status": "success",
  "payload": {
    "_id": "507f1f77bcf86cd799439011",
    "name": "Laptop",
    "price": 999.99,
    "category": "electronics",
    "available": true
  }
}

POST /api/products

Crea un nuevo producto.

Body (JSON):

{
  "name": "Laptop",
  "price": 999.99,
  "category": "electronics",
  "available": true
}

Respuesta (201):

{
  "status": "success",
  "payload": {
    "_id": "507f1f77bcf86cd799439011",
    "name": "Laptop",
    "price": 999.99,
    "category": "electronics",
    "available": true,
    "createdAt": "2024-03-19T10:30:00.000Z"
  }
}

PUT /api/products/:pid

Actualiza un producto existente.

Body (JSON):

{
  "price": 899.99,
  "available": false
}

Respuesta (200):

{
  "status": "success",
  "payload": {
    "_id": "507f1f77bcf86cd799439011",
    "name": "Laptop",
    "price": 899.99,
    "category": "electronics",
    "available": false
  }
}

DELETE /api/products/:pid

Elimina un producto.

Respuesta (200):

{
  "status": "success",
  "payload": {
    "_id": "507f1f77bcf86cd799439011",
    "name": "Laptop",
    "price": 999.99
  }
}

🛒 Carritos

POST /api/carts

Crea un nuevo carrito vacío.

Respuesta (201):

{
  "status": "success",
  "payload": {
    "_id": "507f1f77bcf86cd799439012",
    "products": [],
    "__v": 0
  }
}

GET /api/carts/:cid

Obtiene un carrito con todos los productos poblados.

Ejemplo:

GET /api/carts/507f1f77bcf86cd799439012

Respuesta (200):

{
  "status": "success",
  "payload": {
    "_id": "507f1f77bcf86cd799439012",
    "products": [
      {
        "_id": "507f1f77bcf86cd799439013",
        "product": {
          "_id": "507f1f77bcf86cd799439011",
          "name": "Laptop",
          "price": 999.99,
          "category": "electronics"
        },
        "quantity": 2
      }
    ]
  }
}

POST /api/carts/:cid/products/:pid

Agrega un producto al carrito o incrementa su cantidad.

Body (JSON):

{
  "quantity": 2
}

Respuesta (200):

{
  "products": [
    {
      "_id": "507f1f77bcf86cd799439013",
      "product": "507f1f77bcf86cd799439011",
      "quantity": 2
    }
  ]
}

PUT /api/carts/:cid/products/:pid

Actualiza la cantidad de un producto específico en el carrito.

Body (JSON):

{
  "quantity": 5
}

Respuesta (200):

{
  "status": "success",
  "payload": {
    "_id": "507f1f77bcf86cd799439012",
    "products": [
      {
        "product": "507f1f77bcf86cd799439011",
        "quantity": 5
      }
    ]
  }
}

DELETE /api/carts/:cid/products/:pid

Elimina un producto específico del carrito.

Respuesta (200):

{
  "status": "success",
  "payload": {
    "_id": "507f1f77bcf86cd799439012",
    "products": []
  }
}

PUT /api/carts/:cid

Actualiza todos los productos del carrito.

Body (JSON):

{
  "products": [
    {
      "product": "507f1f77bcf86cd799439011",
      "quantity": 3
    }
  ]
}

Respuesta (200):

{
  "status": "success",
  "payload": {
    "_id": "507f1f77bcf86cd799439012",
    "products": [...]
  }
}

DELETE /api/carts/:cid

Vacía completamente el carrito.

Respuesta (200):

{
  "status": "success",
  "payload": {
    "_id": "507f1f77bcf86cd799439012",
    "products": []
  }
}

🔄 Flujos de Aplicación

Flujo de Compra Completo

graph TD
    A["🏠 Usuario entra a /home"] --> B["📋 Ve lista de productos"]
    B --> C["✅ Selecciona productos"]
    C --> D{¿Tiene carrito?}
    D -->|No| E["📦 POST /api/carts<br/>Crear nuevo carrito"]
    D -->|Sí| F["Usar carrito existente"]
    E --> G["Carrito creado"]
    G --> H["🛒 GET /api/carts/:cid<br/>Ver carrito vacío"]
    F --> H
    H --> I["➕ POST /api/carts/:cid/products/:pid<br/>Agregar producto 1"]
    I --> J["➕ POST /api/carts/:cid/products/:pid<br/>Agregar producto 2"]
    J --> K["✏️ PUT /api/carts/:cid/products/:pid<br/>Cambiar cantidad"]
    K --> L["👁️ GET /api/carts/:cid<br/>Ver carrito actualizado"]
    L --> M{¿Continuar?}
    M -->|Sí| N["❌ DELETE /api/carts/:cid/products/:pid<br/>Eliminar producto"]
    N --> L
    M -->|No| O["💳 Proceder al pago"]
    O --> P["✅ Compra exitosa"]
    
    style A fill:#e1f5ff
    style B fill:#e1f5ff
    style C fill:#e1f5ff
    style P fill:#c8e6c9
Loading

Flujo de Gestión de Productos (Admin)

graph LR
    A["🔑 Admin"] --> B{Acción}
    
    B -->|Crear| C["📝 POST /api/products"]
    C --> D["✅ Producto creado"]
    
    B -->|Leer| E["👁️ GET /api/products"]
    E --> F["📊 Lista de productos"]
    
    B -->|Actualizar| G["✏️ PUT /api/products/:pid"]
    G --> H["✅ Producto actualizado"]
    
    B -->|Eliminar| I["🗑️ DELETE /api/products/:pid"]
    I --> J["✅ Producto eliminado"]
    
    F --> K["📊 Visualizar"]
    K --> L["🔍 Filtrar/Paginar/Ordenar"]
    
    style D fill:#c8e6c9
    style H fill:#c8e6c9
    style J fill:#c8e6c9
    style F fill:#bbdefb
Loading

Flujo de Datos en Petición GET /api/products

graph TD
    Client["🌐 Cliente"]
    Express["Express Router"]
    Controller["Products Controller"]
    Model["Product Model"]
    MongoDB["MongoDB"]
    
    Client -->|GET /api/products?page=1&limit=10| Express
    Express -->|Pasa a| Controller
    Controller -->|Extrae params:<br/>page, limit, sort, query| Controller
    Controller -->|Construye filter<br/>y options| Controller
    Controller -->|Product.paginate<br/>filter, options| Model
    Model -->|Consulta en<br/>MongoDB| MongoDB
    MongoDB -->|Retorna docs<br/>y metadata| Model
    Model -->|Retorna resultado| Controller
    Controller -->|Respuesta JSON<br/>con status:success| Express
    Express -->|Status 200| Client
    
    style Client fill:#e1f5ff
    style Express fill:#f3e5f5
    style Controller fill:#fff3e0
    style Model fill:#f1f8e9
    style MongoDB fill:#eceff1
Loading

Flujo de Socket.io (Tiempo Real)

graph TB
    Browser["🌐 Navegador"]
    WebSocket["⚡ WebSocket"]
    SocketIO["Socket.io Server"]
    DB["💾 MongoDB"]
    
    Browser -->|Conecta| WebSocket
    WebSocket -->|socket on connection| SocketIO
    SocketIO -->|Emite 'Nuevo cliente conectado'| SocketIO
    Browser -->|Escucha eventos| SocketIO
    SocketIO -->|socket on disconnect| SocketIO
    SocketIO -->|Emite 'Cliente desconectado'| SocketIO
    
    style Browser fill:#e1f5ff
    style WebSocket fill:#f3e5f5
    style SocketIO fill:#fff3e0
    style DB fill:#e8f5e9
Loading

🏭 Modelos de Datos

📦 Modelo Product

{
  _id: ObjectId,
  name: String (requerido),
  price: Number (requerido),
  category: String (requerido),
  available: Boolean (default: true),
  createdAt: Timestamp,
  updatedAt: Timestamp
}

Ejemplo:

{
  "_id": "507f1f77bcf86cd799439011",
  "name": "Laptop Dell",
  "price": 1299.99,
  "category": "electronics",
  "available": true,
  "createdAt": "2024-03-19T10:30:00.000Z",
  "updatedAt": "2024-03-19T10:30:00.000Z"
}

🛒 Modelo Cart

{
  _id: ObjectId,
  products: [
    {
      product: ObjectId (referencia a Product),
      quantity: Number (default: 1)
    }
  ]
}

Ejemplo:

{
  "_id": "507f1f77bcf86cd799439012",
  "products": [
    {
      "_id": "507f1f77bcf86cd799439013",
      "product": "507f1f77bcf86cd799439011",
      "quantity": 2
    },
    {
      "_id": "507f1f77bcf86cd799439014",
      "product": "507f1f77bcf86cd799439015",
      "quantity": 1
    }
  ]
}

📁 Detalles de Archivos Clave

app.js

Propósito: Archivo principal de la aplicación

  • Configuración de Express
  • Setup de Handlebars
  • Conexión a MongoDB
  • Creación del servidor HTTP con Socket.io
  • Definición de rutas

socket.js

Propósito: Configuración de Socket.io

  • Manejo de conexiones
  • Eventos de desconexión
  • Estructura para emitir eventos en tiempo real

config/db/connect.config.js

Propósito: Conexión a MongoDB

  • Conexión a la base de datos ecommerce
  • Manejo de errores de conexión

config/models/product.js

Propósito: Schema del producto

  • Validación de campos requeridos
  • Plugin de paginación
  • Timestamps automáticos

config/models/cart.js

Propósito: Schema del carrito

  • Referencia a productos
  • Array de productos con cantidades
  • Validación de estructura

controllers/products.controller.js

Propósito: Lógica de negocio para productos

  • getProducts() - Listado con paginación
  • getProductById() - Obtener producto individual
  • createProduct() - Crear producto
  • updateProduct() - Actualizar producto
  • deleteProduct() - Eliminar producto

controllers/carts.controller.js

Propósito: Lógica de negocio para carritos

  • createCart() - Inicializar carrito
  • addProductToCart() - Agregar/incrementar producto
  • getCartById() - Obtener carrito con datos
  • updateCart() - Actualizar todos los productos
  • updateProductQuantity() - Cambiar cantidad específica
  • deleteProductFromCart() - Eliminar producto
  • clearCart() - Vaciar carrito

routes/

  • products.router.js - Rutas API de productos
  • carts.router.js - Rutas API de carritos
  • home.router.js - Ruta de inicio
  • views.router.js - Rutas de vistas renderizadas

views/

  • home.hbs - Página de inicio
  • products.hbs - Listado de productos
  • cart.hbs - Vista del carrito
  • realTimeProducts.hbs - Productos en tiempo real
  • layouts/main.hbs - Layout base

📦 Tecnologías Utilizadas

Backend

Tecnología Versión Propósito
Node.js - Runtime JavaScript
Express.js ^5.2.1 Framework web
MongoDB - Base de datos NoSQL
Mongoose ^9.2.2 ODM para MongoDB
Socket.io ^4.8.3 WebSockets en tiempo real
Nodemon 3.1.11 Hot reload en desarrollo

Frontend

Tecnología Propósito
Handlebars Motor de plantillas
Bootstrap 5.3.0 - Framework CSS
HTML5 Estructura
CSS3 Estilos

Herramientas

Herramienta Propósito
Postman Testing de API
MongoDB Compass Visualización de BD
Git Control de versiones

📜 Scripts Disponibles

npm start

Inicia la aplicación en modo producción.

npm start

npm run dev

Inicia la aplicación en modo desarrollo con nodemon (hot-reload).

npm run dev

npm test

Script para ejecutar tests (actualmente no configurado).

npm test

🔐 Seguridad y Validación

Respuestas de Error

Producto no encontrado (404):

{
  "status": "error",
  "message": "Producto no encontrado"
}

Carrito no encontrado (404):

{
  "status": "error",
  "message": "Carrito no encontrado"
}

Error del servidor (500):

{
  "status": "error",
  "message": "Descripción del error"
}

Validación

  • Los campos requeridos se validan a nivel de schema Mongoose
  • Se retornan errores descriptivos en JSON
  • Validación automática de tipos de datos

📧 Contacto y Soporte

Autor: Emmanuel Alejandro Lopez Vergara
Repositorio: Backend-I
Licencia: MIT


📄 Licencia

Este proyecto está bajo la licencia MIT. Ver LICENSE para más detalles.


🙏 Agradecimientos

  • Express.js por el excelente framework
  • MongoDB por la flexibilidad en datos
  • Socket.io por WebSockets simplificado
  • Handlebars por templating elegante
  • Bootstrap por el CSS responsive

Última actualización: Marzo 19, 2024
Versión: 1.0.0

About

Server Express

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors