codigo0/backend/dist/src/index.js

135 lines
5.1 KiB
JavaScript
Raw Normal View History

2026-01-19 08:10:16 +00:00
/**
* EMERGES TES - Backend API Server
*
2026-01-19 08:10:16 +00:00
* FASE 1: Infraestructura Base
*
2026-01-19 08:10:16 +00:00
* IMPORTANTE: Este es un esqueleto básico.
* La implementación completa se hará progresivamente.
*/
import express from 'express';
import cors from 'cors';
import dotenv from 'dotenv';
import { join } from 'path';
import { testConnection } from '../config/database.js';
import { validateSecurityConfig } from './config/security.js';
import { validateEnv } from './config/env.js';
import { getCorsConfig } from './config/cors.js';
import { securityHeaders } from './middleware/security-headers.js';
import { generalLimiter } from './middleware/rate-limit.js';
import logger, { logError } from './utils/logger.js';
import requestLogger from './middleware/request-logger.js';
import authRoutes from './routes/auth.js'; // TypeScript
import contentRoutes from './routes/content.js'; // TypeScript
import statsRoutes from './routes/stats.js'; // TypeScript
import contentPackRoutes from './routes/content-pack.js'; // TypeScript
import contentPackAdminRoutes from './routes/content-pack-admin.js'; // TypeScript
import mediaRoutes from './routes/media.js'; // TypeScript
import contentResourcesRoutes from './routes/content-resources.js'; // TypeScript
import scormRoutes from './routes/scorm.js'; // TypeScript
import validationRoutes from './routes/validation.js'; // TypeScript
import drugsRoutes from './routes/drugs.js'; // TypeScript
import webhookRoutes from './routes/webhook.js'; // TypeScript
import healthRoutes from './routes/health.js'; // TypeScript
2026-01-19 08:10:16 +00:00
dotenv.config();
// ✅ VALIDACIÓN CRÍTICA DE SEGURIDAD AL STARTUP
// Si alguna validación falla, la app no arranca
logger.info('🔒 Validando configuración de seguridad...');
validateSecurityConfig();
validateEnv();
logger.info('✅ Configuración validada correctamente');
const app = express();
const PORT = process.env.PORT || process.env.API_PORT || 3000;
// ✅ SECURITY HEADERS (Helmet.js)
app.use(securityHeaders);
// ✅ CORS MEJORADO (con validación de orígenes)
app.use(cors(getCorsConfig()));
// ✅ RATE LIMITING GENERAL
app.use(generalLimiter);
// ✅ REQUEST LOGGING
app.use(requestLogger);
// ✅ JSON PARSING
app.use(express.json({ limit: '10mb' })); // Limitar tamaño de payload
// Servir archivos estáticos de media
app.use('/storage/media', express.static(join(process.cwd(), 'storage', 'media')));
// Health check básico (mantener para compatibilidad)
app.get('/health', async (_req, res) => {
const dbStart = Date.now();
const dbConnected = await testConnection();
const dbResponseTime = Date.now() - dbStart;
const health = {
status: dbConnected ? 'ok' : 'degraded',
timestamp: new Date().toISOString(),
database: dbConnected ? 'connected' : 'disconnected',
databaseResponseTime: dbResponseTime,
uptime: process.uptime(),
memory: {
used: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
total: Math.round(process.memoryUsage().heapTotal / 1024 / 1024),
},
};
if (!dbConnected) {
logger.warn('Health check: Database disconnected');
}
res.json(health);
2026-01-19 08:10:16 +00:00
});
// Root endpoint
app.get('/', (_req, res) => {
res.json({
message: 'EMERGES TES Backend API',
version: '1.0.0',
endpoints: {
auth: '/api/auth',
content: '/api/content',
stats: '/api/stats',
contentPack: '/api/content-pack',
health: '/health',
},
});
2026-01-19 08:10:16 +00:00
});
// API Routes
app.use('/api/auth', authRoutes);
app.use('/api/content', contentRoutes);
app.use('/api/stats', statsRoutes);
app.use('/api/content-pack', contentPackRoutes);
app.use('/api/admin/content-pack', contentPackAdminRoutes);
app.use('/api/media', mediaRoutes);
app.use('/api/content', contentResourcesRoutes);
app.use('/api/scorm', scormRoutes);
app.use('/api/validation', validationRoutes);
app.use('/api/drugs', drugsRoutes);
app.use('/api/webhook', webhookRoutes);
app.use('/api/health', healthRoutes);
2026-01-19 08:10:16 +00:00
// Iniciar servidor
app.listen(PORT, async () => {
logger.info('🚀 EMERGES TES Backend API iniciado', {
port: PORT,
environment: process.env.NODE_ENV || 'development',
nodeVersion: process.version,
});
logger.info('📍 Endpoints disponibles', {
health: `http://localhost:${PORT}/health`,
auth: `http://localhost:${PORT}/api/auth`,
content: `http://localhost:${PORT}/api/content`,
});
// Test de conexión a BD
const dbConnected = await testConnection();
if (dbConnected) {
logger.info('✅ Conexión a base de datos establecida');
}
else {
logger.error('❌ Error conectando a base de datos');
}
2026-01-19 08:10:16 +00:00
});
// Manejo de errores
process.on('SIGTERM', async () => {
logger.info('SIGTERM recibido, cerrando servidor...');
process.exit(0);
2026-01-19 08:10:16 +00:00
});
process.on('unhandledRejection', (error) => {
logError(error instanceof Error ? error : new Error(String(error)), { type: 'unhandledRejection' });
2026-01-19 08:10:16 +00:00
});
process.on('uncaughtException', (error) => {
logError(error, { type: 'uncaughtException' });
process.exit(1);
2026-01-19 08:10:16 +00:00
});
//# sourceMappingURL=index.js.map