# Backend MVP - API de Gestión de Actividades

Este es un proyecto backend desarrollado con Node.js y Express para gestionar actividades de usuarios con sistema de gamificación (insignias, metas, niveles).

## Tabla de Contenidos

1. [Tecnologías Utilizadas](#tecnologías-utilizadas)
2. [Estructura del Proyecto](#estructura-del-proyecto)
3. [Configuración Inicial](#configuración-inicial)
4. [Arquitectura y Flujo de Datos](#arquitectura-y-flujo-de-datos)
5. [Endpoints Disponibles](#endpoints-disponibles)
6. [Explicación del Código](#explicación-del-código)

---

## Tecnologías Utilizadas

- **Node.js**: Entorno de ejecución de JavaScript
- **Express**: Framework web para crear la API REST
- **MySQL**: Base de datos relacional
- **JWT (JSON Web Tokens)**: Autenticación basada en tokens
- **bcryptjs**: Encriptación de contraseñas
- **express-validator**: Validación de datos de entrada
- **dotenv**: Gestión de variables de entorno
- **cors**: Permitir peticiones desde el frontend
- **morgan**: Logger de peticiones HTTP

---

## Estructura del Proyecto

```
backend-mvp/
│
├── server.js                    # Punto de entrada principal
│
├── src/
│   ├── config/
│   │   └── db.js               # Configuración del pool de MySQL
│   │
│   ├── middleware/
│   │   ├── auth.js             # Middleware de autenticación (legacy)
│   │   ├── requireAdmin.js     # Middleware para verificar rol admin
│   │   └── handleValidation.js # Middleware para procesar validaciones
│   │
│   ├── utils/
│   │   └── jwt.js              # Utilidades JWT (sign, verify, requireAuth)
│   │
│   ├── validators/
│   │   ├── auth.validators.js  # Validaciones para autenticación
│   │   ├── actividades.validators.js
│   │   ├── categorias.validators.js
│   │   └── ... (otros validadores)
│   │
│   └── routes/
│       ├── auth.routes.js      # Rutas de autenticación (login, register)
│       ├── actividades.routes.js
│       ├── categorias.routes.js
│       ├── roles.routes.js
│       ├── insignias.routes.js
│       ├── metas.routes.js
│       ├── niveles.routes.js
│       ├── notificaciones.routes.js
│       ├── agenda.routes.js
│       ├── registroActividad.routes.js
│       ├── usuarioMetricas.routes.js
│       ├── usuarioInsignias.routes.js
│       ├── usuarioRoles.routes.js
│       └── adminMetrics.routes.js
│
├── .env                         # Variables de entorno (NO incluir en git)
├── package.json                 # Dependencias del proyecto
└── README.md                    # Este archivo
```

---

## Configuración Inicial

### 1. Instalar dependencias

```bash
npm install
```

### 2. Configurar variables de entorno

Crear un archivo `.env` en la raíz del proyecto con el siguiente contenido:

```env
# Base de datos
DB_HOST=localhost
DB_USER=tu_usuario
DB_PASS=tu_contraseña
DB_NAME=nombre_base_datos
DB_PORT=3306

# JWT
JWT_SECRET=tu_secreto_super_seguro_cambiar_en_produccion

# Servidor
PORT=3000
```

### 3. Configurar la base de datos

Asegúrate de tener MySQL instalado y crea las tablas necesarias. El proyecto espera las siguientes tablas:

- `usuarios`: Información de usuarios (id_usuario, nombre, apellido, email, password_hash, genero, fecha_registro, activo)
- `roles`: Roles del sistema (id_rol, nombre, descripcion)
- `usuarios_roles`: Relación muchos a muchos entre usuarios y roles
- `categorias`: Categorías de actividades
- `actividades`: Actividades del sistema
- `insignias`: Insignias/badges del sistema de gamificación
- `metas`: Metas/objetivos de usuarios
- `niveles`: Niveles del sistema de progreso
- `notificaciones`: Sistema de notificaciones
- `agenda`: Calendario/planificación de actividades
- `registro_actividad`: Registro de actividades completadas
- `usuario_metricas`: Estadísticas de usuarios
- `usuario_insignias`: Insignias obtenidas por usuarios

### 4. Iniciar el servidor

```bash
node server.js
```

El servidor estará disponible en `http://localhost:3000` (o el puerto configurado en `.env`).

---

## Arquitectura y Flujo de Datos

### Flujo General de una Petición

```
1. Cliente (Frontend) → HTTP Request
   ↓
2. CORS Middleware (permite peticiones del frontend)
   ↓
3. Body Parser (convierte JSON a objeto JavaScript)
   ↓
4. Morgan Logger (registra la petición en consola)
   ↓
5. Router (encuentra la ruta correspondiente)
   ↓
6. Validadores (express-validator verifica datos)
   ↓
7. handleValidation (procesa errores de validación)
   ↓
8. Middlewares de Autenticación (requireAuth / requireAdmin)
   ↓
9. Lógica de la Ruta (consultas a BD, procesamiento)
   ↓
10. Response (JSON con resultado o error)
    ↓
11. Cliente recibe la respuesta
```

### Flujo de Autenticación

```
REGISTRO:
Usuario → POST /api/auth/register → Validación → Hash password
  → Insertar en BD → Generar JWT → Devolver token + user

LOGIN:
Usuario → POST /api/auth/login → Validación → Buscar en BD
  → Verificar password → Generar JWT → Devolver token + user

RUTAS PROTEGIDAS:
Usuario → Petición con header "Authorization: Bearer <token>"
  → requireAuth middleware → Verificar token → Adjuntar req.user
  → Continuar a la ruta → Devolver respuesta
```

### Flujo de Validación

```
Cliente envía datos → Validador (express-validator marca errores)
  → handleValidation middleware
    → Si hay errores: devuelve 400 con lista de errores
    → Si no hay errores: continúa a la lógica de la ruta
```

---

## Endpoints Disponibles

### Autenticación (`/api/auth`)

| Método | Endpoint | Descripción | Auth | Body |
|--------|----------|-------------|------|------|
| POST | `/api/auth/register` | Registrar nuevo usuario | No | `{ nombre, apellido, email, genero, password }` |
| POST | `/api/auth/login` | Iniciar sesión | No | `{ email, password }` |
| GET | `/api/auth/me` | Obtener perfil + roles | Sí | - |
| PUT | `/api/auth/me/profile` | Actualizar perfil | Sí | `{ nombre?, apellido? }` |
| PUT | `/api/auth/me/password` | Cambiar contraseña | Sí | `{ actual, nueva }` |

### Catálogos

| Endpoint | Descripción |
|----------|-------------|
| `/api/categorias` | CRUD de categorías de actividades |
| `/api/roles` | CRUD de roles del sistema |
| `/api/actividades` | CRUD de actividades |
| `/api/insignias` | CRUD de insignias/badges |
| `/api/metas` | CRUD de metas/objetivos |
| `/api/niveles` | CRUD de niveles |

### Gestión de Usuario

| Endpoint | Descripción |
|----------|-------------|
| `/api/notificaciones` | Notificaciones del usuario |
| `/api/agenda` | Agenda/calendario de actividades |
| `/api/registroactividad` | Registro de actividades completadas |
| `/api/metricas` | Métricas y estadísticas del usuario |
| `/api/usuario-insignias` | Insignias obtenidas por el usuario |
| `/api/usuario-roles` | Roles asignados al usuario |

### Administración

| Endpoint | Descripción |
|----------|-------------|
| `/api/admin/metrics` | Métricas administrativas del sistema |

### Rutas de Prueba

| Método | Endpoint | Descripción |
|--------|----------|-------------|
| GET | `/public` | Ruta pública de prueba |
| GET | `/__ping` | Health check sin autenticación |
| GET | `/api/admin/_ping_noauth` | Ping admin sin auth |
| GET | `/api/admin/_ping_token` | Ping con autenticación |

---

## Explicación del Código

### 1. Punto de Entrada (`server.js`)

Este es el archivo principal que:
1. Carga las variables de entorno con `dotenv`
2. Configura Express y los middlewares globales (CORS, body parser, logger)
3. Registra todas las rutas de la aplicación
4. Inicia el servidor en el puerto especificado

**Ver:** [`server.js`](./server.js) para documentación detallada línea por línea.

---

### 2. Configuración de Base de Datos (`src/config/db.js`)

Crea un **pool de conexiones** a MySQL usando `mysql2/promise`. Un pool reutiliza conexiones en lugar de crear una nueva cada vez, mejorando el rendimiento.

**Configuración clave:**
- `connectionLimit: 10` → Máximo 10 conexiones simultáneas
- `namedPlaceholders: true` → Permite usar `:nombre` en queries
- Lee las credenciales desde variables de entorno (`.env`)

**Exporta:** El pool que se importa en todas las rutas.

**Ver:** [`src/config/db.js`](./src/config/db.js) para más detalles.

---

### 3. Utilidades JWT (`src/utils/jwt.js`)

Maneja todo lo relacionado con JSON Web Tokens:

**Funciones principales:**

1. **`signToken(payload, expiresIn)`**
   - Genera un token JWT firmado
   - Usado en register/login para crear tokens
   - Incluye datos del usuario (id_usuario, email)

2. **`verifyTokenPayload(token)`**
   - Verifica que un token sea válido
   - Extrae y devuelve el payload decodificado

3. **`requireAuth(req, res, next)`** (Middleware)
   - Protege rutas que requieren autenticación
   - Extrae el token del header `Authorization: Bearer <token>`
   - Verifica el token y adjunta `req.user` con los datos del usuario
   - Si el token es inválido o expiró, devuelve error 401

**Flujo de uso:**
```javascript
// En una ruta protegida:
router.get('/perfil', requireAuth, (req, res) => {
  console.log(req.user); // { id_usuario: 123, email: 'user@mail.com' }
  // ... lógica de la ruta
});
```

**Ver:** [`src/utils/jwt.js`](./src/utils/jwt.js) para documentación completa.

---

### 4. Middlewares

#### a) `handleValidation` (`src/middleware/handleValidation.js`)

Procesa los resultados de `express-validator`:
- Recoge los errores marcados por los validadores
- Si hay errores: devuelve `400 Bad Request` con la lista
- Si no hay errores: continúa a la ruta

**Uso:**
```javascript
router.post('/register', registerValidator, handleValidation, async (req, res) => {
  // Si llega aquí, los datos ya fueron validados
});
```

#### b) `requireAdmin` (`src/middleware/requireAdmin.js`)

Verifica que el usuario autenticado sea administrador:
1. Verifica que `req.user` exista (debe usarse DESPUÉS de `requireAuth`)
2. Consulta la BD para verificar si el usuario tiene rol 'admin'
3. Si es admin: continúa; si no: devuelve `403 Forbidden`

**Uso:**
```javascript
router.get('/admin/users', requireAuth, requireAdmin(), async (req, res) => {
  // Solo admins pueden llegar aquí
});
```

**Ver:** [`src/middleware/`](./src/middleware/) para más detalles.

---

### 5. Validadores (`src/validators/`)

Definen reglas de validación usando `express-validator`.

**Ejemplo:** `auth.validators.js`

```javascript
const registerValidator = [
  body('nombre').trim().notEmpty().withMessage('Nombre requerido'),
  body('email').isEmail().withMessage('Email inválido'),
  body('password').isLength({ min: 6 }).withMessage('Mínimo 6 caracteres'),
];
```

**Flujo:**
1. Se aplica como middleware en la ruta
2. `express-validator` verifica cada campo
3. `handleValidation` recoge los errores y responde

**Ver:** [`src/validators/auth.validators.js`](./src/validators/auth.validators.js) para ejemplo completo.

---

### 6. Rutas (`src/routes/`)

Cada archivo de rutas maneja un recurso específico (usuarios, actividades, etc.).

**Ejemplo:** `auth.routes.js`

#### **POST /api/auth/register**

**Flujo completo:**
1. `registerValidator` valida nombre, email, password
2. `handleValidation` verifica errores
3. Verifica que el email no esté registrado
4. Hashea la contraseña con `bcrypt`
5. Inserta el usuario en la BD
6. Genera un token JWT con `signToken()`
7. Devuelve el token + datos del usuario

**Request:**
```json
{
  "nombre": "Juan",
  "apellido": "Pérez",
  "email": "juan@mail.com",
  "genero": "M",
  "password": "miPassword123"
}
```

**Response (201):**
```json
{
  "msg": "Usuario registrado con éxito",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id_usuario": 1,
    "nombre": "Juan",
    "apellido": "Pérez",
    "email": "juan@mail.com",
    "genero": "M"
  }
}
```

#### **POST /api/auth/login**

**Flujo completo:**
1. `loginValidator` valida email y password
2. Busca el usuario por email en la BD
3. Verifica que el usuario esté activo
4. Compara la contraseña con `bcrypt.compare()`
5. Genera token JWT
6. Devuelve token + datos del usuario

**Request:**
```json
{
  "email": "juan@mail.com",
  "password": "miPassword123"
}
```

**Response (200):**
```json
{
  "msg": "Login exitoso",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id_usuario": 1,
    "nombre": "Juan",
    ...
  }
}
```

**Ver:** [`src/routes/auth.routes.js`](./src/routes/auth.routes.js) para documentación línea por línea.

---

## Diagrama de Componentes

```
┌─────────────────────────────────────────────────────────────┐
│                         CLIENTE                              │
│                   (Frontend - React/Vue)                     │
└────────────────────────┬────────────────────────────────────┘
                         │ HTTP Request
                         │ Authorization: Bearer <token>
                         ↓
┌─────────────────────────────────────────────────────────────┐
│                      SERVER.JS                               │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ MIDDLEWARES GLOBALES                                 │   │
│  │ - CORS (permite frontend)                            │   │
│  │ - express.json() (parsea body)                       │   │
│  │ - morgan (logger)                                    │   │
│  └──────────────────────────────────────────────────────┘   │
└────────────────────────┬────────────────────────────────────┘
                         │
                         ↓
┌─────────────────────────────────────────────────────────────┐
│                    ROUTER (Rutas)                            │
│  /api/auth → auth.routes.js                                 │
│  /api/actividades → actividades.routes.js                   │
│  /api/categorias → categorias.routes.js                     │
│  ...                                                         │
└────────────────────────┬────────────────────────────────────┘
                         │
                         ↓
┌─────────────────────────────────────────────────────────────┐
│               VALIDADORES + handleValidation                 │
│  - registerValidator (express-validator)                    │
│  - handleValidation (procesa errores)                       │
└────────────────────────┬────────────────────────────────────┘
                         │
                         ↓
┌─────────────────────────────────────────────────────────────┐
│                   MIDDLEWARES DE AUTH                        │
│  - requireAuth (verifica JWT)                               │
│  - requireAdmin (verifica rol admin)                        │
└────────────────────────┬────────────────────────────────────┘
                         │
                         ↓
┌─────────────────────────────────────────────────────────────┐
│                  LÓGICA DE LA RUTA                          │
│  - Consultas a BD (pool)                                    │
│  - Procesamiento de datos                                   │
│  - Generación de respuesta                                  │
└────────────────────────┬────────────────────────────────────┘
                         │
                         ↓
┌─────────────────────────────────────────────────────────────┐
│                     BASE DE DATOS                            │
│                        (MySQL)                               │
│  - usuarios, roles, actividades, insignias, etc.            │
└─────────────────────────────────────────────────────────────┘
```

---

## Conceptos Clave para Entender

### 1. **Middleware**
Funciones que se ejecutan ANTES de la lógica de la ruta. Se ejecutan en orden:
```javascript
app.use(cors());         // 1. Permite CORS
app.use(express.json()); // 2. Parsea JSON
// ...
router.post('/login', loginValidator, handleValidation, async (req, res) => {
  // 3. loginValidator → 4. handleValidation → 5. Esta función
});
```

### 2. **JWT (JSON Web Token)**
Token firmado que contiene información del usuario. Permite autenticación sin sesiones:
- **Frontend:** Guarda el token (localStorage/cookie)
- **Cada petición:** Envía el token en header `Authorization: Bearer <token>`
- **Backend:** Verifica el token y extrae datos del usuario

### 3. **Bcrypt**
Librería para hashear contraseñas de forma segura:
- `bcrypt.hash(password, 10)` → Hashea la contraseña
- `bcrypt.compare(password, hash)` → Verifica si coinciden
- **NUNCA** se guardan contraseñas en texto plano

### 4. **Pool de Conexiones**
En lugar de abrir/cerrar conexiones a MySQL constantemente, un pool mantiene conexiones abiertas y las reutiliza, mejorando el rendimiento.

### 5. **Express Router**
Permite modularizar las rutas:
```javascript
// En server.js
app.use('/api/auth', authRoutes);

// En auth.routes.js
router.post('/login', ...); // Resulta en: POST /api/auth/login
```

---

## Para Estudiantes

### Cómo leer este código paso a paso

1. **Empieza por `server.js`**: Entiende cómo se inicia el servidor y se registran las rutas.

2. **Lee `src/config/db.js`**: Aprende cómo se conecta a MySQL.

3. **Estudia `src/utils/jwt.js`**: Comprende cómo funciona la autenticación con JWT.

4. **Analiza `src/routes/auth.routes.js`**: Sigue el flujo completo de register/login.

5. **Revisa los middlewares**: Entiende cómo `requireAuth`, `handleValidation`, etc. protegen y validan.

6. **Explora otros módulos de rutas**: Aplica lo aprendido a otras funcionalidades.

### Preguntas frecuentes

**¿Cómo funciona el login?**
1. Usuario envía email + password
2. Backend busca el usuario en BD
3. Compara password con bcrypt
4. Genera un JWT con los datos del usuario
5. Devuelve el JWT al frontend
6. Frontend guarda el JWT y lo envía en cada petición

**¿Cómo proteger una ruta?**
```javascript
router.get('/perfil', requireAuth, async (req, res) => {
  // requireAuth verifica el JWT antes de ejecutar esto
  const userId = req.user.id_usuario;
  // ...
});
```

**¿Cómo validar datos?**
```javascript
const miValidator = [
  body('email').isEmail(),
  body('edad').isInt({ min: 18 })
];

router.post('/ruta', miValidator, handleValidation, async (req, res) => {
  // Si llega aquí, los datos ya están validados
});
```

---

## Buenas Prácticas Implementadas

1. **Seguridad:**
   - Contraseñas hasheadas con bcrypt
   - Autenticación con JWT
   - Validación de datos de entrada
   - Variables sensibles en `.env`

2. **Código limpio:**
   - Comentarios explicativos
   - Separación de responsabilidades (rutas, middlewares, validadores)
   - Nombres descriptivos de variables y funciones

3. **Arquitectura:**
   - Modular (cada funcionalidad en su archivo)
   - Reutilizable (middlewares, validadores)
   - Escalable (fácil agregar nuevas rutas)

---

## Autor

Proyecto educativo desarrollado para aprendizaje de backend con Node.js y Express.

---

## Licencia

Este es un proyecto de escuela sin licencia específica.
