back/server.js

209 lines
7.8 KiB
JavaScript

/**
* ========================================
* SERVIDOR PRINCIPAL - PUNTO DE ENTRADA
* ========================================
*
* Este archivo es el punto de inicio de la aplicación backend.
* Configura Express, middlewares, y registra todas las rutas.
*
* FLUJO DE EJECUCIÓN:
* 1. Carga variables de entorno (.env)
* 2. Inicializa Express y configura middlewares globales
* 3. Registra todas las rutas de la aplicación
* 4. Inicia el servidor en el puerto especificado
*/
// ========================================
// 1. CARGA DE VARIABLES DE ENTORNO
// ========================================
// Carga las variables del archivo .env al proceso (process.env)
// Variables necesarias: DB_HOST, DB_USER, DB_PASS, DB_NAME, JWT_SECRET, PORT
require('dotenv').config();
// ========================================
// 2. IMPORTACIÓN DE DEPENDENCIAS
// ========================================
const express = require('express'); // Framework web para Node.js
const cors = require('cors'); // Permite peticiones desde otros dominios (frontend)
const morgan = require('morgan'); // Logger de peticiones HTTP
// Crea la instancia principal de Express
const app = express();
// ========================================
// 3. LOGS DE DIAGNÓSTICO
// ========================================
// Muestra información útil al iniciar el servidor (debugging)
console.log('[CWD]', process.cwd());
console.log('[ENV]', {
DB_HOST: process.env.DB_HOST,
DB_USER: process.env.DB_USER,
DB_NAME: process.env.DB_NAME
// NO imprimas DB_PASSWORD por seguridad
});
// ========================================
// 4. CONFIGURACIÓN DE MIDDLEWARES GLOBALES
// ========================================
// Los middlewares se ejecutan en ORDEN para cada petición
// 4.1 CORS - Permite peticiones desde el frontend (localhost:5173)
// origin: dominio del frontend que puede hacer peticiones
// credentials: permite enviar cookies y headers de autenticación
app.use(cors({
origin: 'http://localhost:5173',
credentials: true
}));
// 4.2 Body Parsers - Procesan el cuerpo de las peticiones
// express.json(): convierte JSON del body a objeto JavaScript (req.body)
// express.urlencoded(): procesa datos de formularios
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 4.3 Morgan - Logger que muestra info de cada petición en consola
// 'dev': formato colorizado con método, ruta, status y tiempo
app.use(morgan('dev'));
// ========================================
// 5. IMPORTACIÓN DE UTILIDADES
// ========================================
// requireAuth: middleware para proteger rutas que requieren autenticación
// Se usa en rutas que necesitan verificar el token JWT
const { requireAuth } = require('./src/utils/jwt');
// ========================================
// 6. REGISTRO DE RUTAS
// ========================================
// Cada módulo de rutas maneja un recurso específico
// Todas las rutas comienzan con /api/*
// 6.1 Autenticación y gestión de usuarios
// Rutas: /api/auth/register, /api/auth/login, /api/auth/me
const authRoutes = require('./src/routes/auth.routes');
app.use('/api/auth', authRoutes);
// 6.2 Catálogos del sistema
// Categorías de actividades (Trabajo, Estudio, Deporte, etc.)
const categoriasRoutes = require('./src/routes/categorias.routes');
app.use('/api/categorias', categoriasRoutes);
// Roles de usuarios (Admin, Usuario normal, etc.)
const rolesRoutes = require('./src/routes/roles.routes');
app.use('/api/roles', rolesRoutes);
// 6.3 Actividades del sistema
// CRUD de actividades que los usuarios pueden realizar
const actividadesRoutes = require('./src/routes/actividades.routes');
app.use('/api/actividades', actividadesRoutes);
// 6.4 Sistema de gamificación
// Insignias/badges que los usuarios pueden obtener
const insigniasRoutes = require('./src/routes/insignias.routes');
app.use('/api/insignias', insigniasRoutes);
// Metas/objetivos que los usuarios pueden definir
const metasRoutes = require('./src/routes/metas.routes');
app.use('/api/metas', metasRoutes);
// Niveles del sistema de progreso
const nivelesRoutes = require('./src/routes/niveles.routes');
app.use('/api/niveles', nivelesRoutes);
// 6.5 Sistema de notificaciones
const notificacionesRoutes = require('./src/routes/notificaciones.routes');
app.use('/api/notificaciones', notificacionesRoutes);
// 6.6 Gestión de tiempo y registros
// Agenda: calendario/planificación de actividades
const agendaRoutes = require('./src/routes/agenda.routes');
app.use('/api/agenda', agendaRoutes);
// Registro de actividades completadas
const registroActividadRoutes = require('./src/routes/registroActividad.routes');
app.use('/api/registroactividad', registroActividadRoutes);
// 6.7 Estadísticas y métricas de usuarios
const usuarioMetricasRoutes = require('./src/routes/usuarioMetricas.routes');
app.use('/api/metricas', usuarioMetricasRoutes);
// 6.8 Relaciones usuario-insignias
const usuarioInsigniasRoutes = require('./src/routes/usuarioInsignias.routes');
app.use('/api/usuario-insignias', usuarioInsigniasRoutes);
// 6.9 Relaciones usuario-roles
const usuarioRolesRoutes = require('./src/routes/usuarioRoles.routes');
app.use('/api/usuario-roles', usuarioRolesRoutes);
// 6.10 Métricas administrativas
const adminMetricsRoutes = require('./src/routes/adminMetrics.routes');
app.use('/api/admin/metrics', adminMetricsRoutes);
// ========================================
// 7. RUTAS DE PRUEBA Y HEALTH CHECK
// ========================================
// Estas rutas son útiles para debugging y verificar que el servidor funciona
// 7.1 Ruta pública de prueba (sin autenticación)
app.get('/public', (req, res) => {
res.json({ ok: true, msg: 'Ruta pública funcionando' });
});
// 7.2 Health check básico
app.get('/__ping', (req, res) => {
res.json({ ok: true, msg: '__ping sin auth' });
});
// 7.3 Health check para admin (sin autenticación)
app.get('/api/admin/_ping_noauth', (req, res) => {
res.json({ ok: true, msg: '_ping sin auth' });
});
// 7.4 Health check con autenticación
// Útil para verificar que el JWT y requireAuth funcionan correctamente
// FLUJO: requireAuth valida el token -> adjunta req.user -> devuelve info del usuario
app.get('/api/admin/_ping_token', requireAuth, (req, res) => {
console.log('>> requireAuth OK, user:', req.user);
res.json({ ok: true, step: 'token', user: req.user });
});
// ========================================
// 8. MANEJADOR DE ERRORES GLOBAL
// ========================================
// IMPORTANTE: Debe ir AL FINAL, después de todas las rutas
// Este middleware captura todos los errores que se pasan con next(err)
app.use((err, req, res, next) => {
// Log del error en consola para debugging
console.error('❌ ERROR GLOBAL:', err);
// En producción, no exponer detalles del error
if (process.env.NODE_ENV === 'production') {
return res.status(err.status || 500).json({
ok: false,
error: 'Error interno del servidor'
});
}
// En desarrollo, mostrar detalles completos
res.status(err.status || 500).json({
ok: false,
error: err.message || 'Error interno del servidor',
stack: err.stack,
details: err
});
});
// ========================================
// 9. INICIO DEL SERVIDOR
// ========================================
// Lee el puerto del .env o usa 3000 por defecto
const PORT = process.env.PORT || 3000;
// Inicia el servidor y escucha en el puerto especificado
app.listen(PORT, () => {
console.log(`\n========================================`);
console.log(`🚀 API escuchando en http://localhost:${PORT}`);
console.log(`📝 Modo: ${process.env.NODE_ENV || 'development'}`);
console.log(`========================================\n`);
});