blackmistcode commited on
Commit
199ff10
·
verified ·
1 Parent(s): bdc6309

fix: use Express 5 catch-all route syntax

Browse files
Files changed (1) hide show
  1. app.js +84 -0
app.js ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Aplicacion Express principal — configuracion de middlewares y montaje de rutas.
3
+ *
4
+ * Middlewares aplicados (en orden):
5
+ * 1. helmet() — headers de seguridad (X-Frame-Options, HSTS, etc.).
6
+ * 2. cors() — CORS con origen configurable (CORS_ORIGIN).
7
+ * 3. rateLimit() — 200 peticiones / 15 min por IP.
8
+ * 4. express.json() — parseo de JSON con limite de 1 MB.
9
+ *
10
+ * Rutas REST montadas bajo /api/v1:
11
+ * - /auth → login, perfil (auth.routes.js)
12
+ * - /markets → listado y detalle de mercados (markets.routes.js)
13
+ * - /markets → senales IA por mercado (signals.routes.js, subruta)
14
+ * - /positions → simulador de posiciones virtuales (positions.routes.js)
15
+ * - /watchlist → lista de seguimiento (watchlist.routes.js)
16
+ * - /alerts → historial de alertas (alerts.routes.js)
17
+ * - /health → healthcheck basico
18
+ *
19
+ * Manejo de errores:
20
+ * - notFound → 404 para rutas no definidas.
21
+ * - errorHandler → 500 generico en produccion, detalles en desarrollo.
22
+ */
23
+
24
+ import express from 'express';
25
+ import cors from 'cors';
26
+ import helmet from 'helmet';
27
+ import rateLimit from 'express-rate-limit';
28
+ import { config } from './config.js';
29
+ import { ok } from './utils/apiResponse.js';
30
+ import authRoutes from './auth/auth.routes.js';
31
+ import marketsRoutes from './markets/markets.routes.js';
32
+ import signalsRoutes from './signals/signals.routes.js';
33
+ import positionsRoutes from './positions/positions.routes.js';
34
+ import watchlistRoutes from './watchlist/watchlist.routes.js';
35
+ import alertsRoutes from './alerts/alerts.routes.js';
36
+ import statsRoutes from './stats/stats.routes.js';
37
+ import preferencesRoutes from './preferences/preferences.routes.js';
38
+ import { notFound } from './middlewares/notFound.js';
39
+ import { errorHandler } from './middlewares/errorHandler.js';
40
+ import { existsSync } from 'node:fs';
41
+
42
+ const app = express();
43
+ app.set('trust proxy', 1);
44
+
45
+ app.use(helmet());
46
+ app.use(cors({ origin: config.CORS_ORIGIN, credentials: true }));
47
+
48
+ // Rate limit: muy permisivo en desarrollo, restrictivo en producción
49
+ const rateLimitMax = config.NODE_ENV === 'production' ? 200 : 5000;
50
+ app.use(
51
+ rateLimit({
52
+ windowMs: 15 * 60 * 1000,
53
+ max: rateLimitMax,
54
+ standardHeaders: true,
55
+ legacyHeaders: false,
56
+ message: { ok: false, error: { code: 'TOO_MANY_REQUESTS', message: 'Rate limit exceeded' } },
57
+ }),
58
+ );
59
+ app.use(express.json({ limit: '1mb' }));
60
+
61
+ app.get('/api/v1/health', (_req, res) => ok(res, { status: 'up' }));
62
+ app.use('/api/v1/auth', authRoutes);
63
+ app.use('/api/v1/markets', marketsRoutes);
64
+ app.use('/api/v1/markets', signalsRoutes);
65
+ app.use('/api/v1/positions', positionsRoutes);
66
+ app.use('/api/v1/watchlist', watchlistRoutes);
67
+ app.use('/api/v1/alerts', alertsRoutes);
68
+ app.use('/api/v1/stats', statsRoutes);
69
+ app.use('/api/v1/preferences', preferencesRoutes);
70
+
71
+ // Servir frontend estático en producción (HuggingFace Spaces / Docker)
72
+ // Detecta si estamos en la raíz del proyecto o dentro de backend/
73
+ const frontendDist = existsSync('../frontend/dist') ? '../frontend/dist' : 'frontend/dist';
74
+ if (config.NODE_ENV === 'production') {
75
+ app.use(express.static(frontendDist));
76
+ app.get('*', (_req, res) => {
77
+ res.sendFile('index.html', { root: frontendDist });
78
+ });
79
+ }
80
+
81
+ app.use(notFound);
82
+ app.use(errorHandler);
83
+
84
+ export default app;