@@ -6,6 +6,7 @@ import { config } from "dotenv";
66import { Server } from "socket.io" ;
77import path from "path" ;
88import { fileURLToPath } from "url" ;
9+ import fs from "fs" ;
910
1011import mealsRoutes from "./routes/mealsRoutes.js" ;
1112import workoutRoutes from "./routes/workoutRoutes.js" ;
@@ -30,23 +31,13 @@ const PORT = process.env.PORT || 8081;
3031
3132const isProduction = process . env . NODE_ENV === "production" ;
3233const clientOrigin = isProduction
33- ? "https://gymero.live" // Production URL
34- : "http://localhost:5173" ; // Local development URL
34+ ? "https://gymero.live"
35+ : "http://localhost:5173" ;
3536
3637if ( isProduction ) {
3738 app . use ( expressSslify . HTTPS ( { trustProtoHeader : true } ) ) ;
3839}
3940
40- // Create a rate limiter
41- // const apiLimiter = rateLimit({
42- // windowMs: 15 * 60 * 1000, // 15 minutes
43- // max: 50, // Limit each IP to 100 requests per windowMs
44- // message: "Too many requests from this IP, please try again later.",
45- // });
46-
47- // // Apply the rate limiter to all API routes
48- // app.use("/api/", apiLimiter);
49-
5041const server = http . createServer ( app ) ;
5142const io = new Server ( server , {
5243 cors : {
@@ -56,6 +47,7 @@ const io = new Server(server, {
5647 } ,
5748} ) ;
5849
50+ // Middleware
5951app . use (
6052 cors ( {
6153 origin : [ clientOrigin ] ,
@@ -66,6 +58,16 @@ app.use(
6658app . use ( express . json ( ) ) ;
6759app . use ( cookieParser ( ) ) ;
6860
61+ // Ensure public directory exists
62+ const publicDir = path . join ( __dirname , "public" ) ;
63+ if ( ! fs . existsSync ( publicDir ) ) {
64+ fs . mkdirSync ( publicDir , { recursive : true } ) ;
65+ }
66+
67+ // Serve static files from the public directory
68+ app . use ( express . static ( publicDir ) ) ;
69+
70+ // API Routes
6971app . use ( "/auth" , authRoutes ) ;
7072app . use ( "/api/users" , userRoutes ) ;
7173app . use ( "/api/workouts" , workoutRoutes ) ;
@@ -77,26 +79,42 @@ app.use("/api/streak", streakRoutes);
7779app . use ( "/api/routines" , gymRoutineRoutes ) ;
7880app . use ( "/api/daily-settings" , dailySettingsRoutes ) ;
7981
80- // Serve static files only in production
82+ // Serve static files in production
8183if ( isProduction ) {
82- const clientPath = path . resolve ( __dirname , "../client/dist" ) ;
84+ // Serve from both public and client/dist directories
85+ const clientPath = path . resolve ( __dirname , "public" ) ;
8386 app . use ( express . static ( clientPath ) ) ;
8487
85- // Define the root route to serve the index.html file
88+ // Health check endpoint
89+ app . get ( "/health" , ( req , res ) => {
90+ res . status ( 200 ) . send ( "OK" ) ;
91+ } ) ;
92+
93+ // Define routes for serving the SPA
8694 app . get ( "/" , ( req , res ) => {
8795 res . sendFile ( path . join ( clientPath , "index.html" ) ) ;
8896 } ) ;
8997
90- // Catch-all route for SPA
98+ // Catch-all route for client-side routing
9199 app . get ( "*" , ( req , res ) => {
92- res . sendFile ( path . join ( clientPath , "index.html" ) ) ;
100+ // First try to serve from public directory
101+ const publicPath = path . join ( __dirname , "public" , req . path ) ;
102+ if ( fs . existsSync ( publicPath ) ) {
103+ res . sendFile ( publicPath ) ;
104+ } else {
105+ // If not found in public, serve the SPA's index.html
106+ res . sendFile ( path . join ( __dirname , "public" , "index.html" ) ) ;
107+ }
93108 } ) ;
94109}
95110
96111// Socket.IO event listeners
97112io . on ( "connection" , ( socket ) => {
113+ console . log ( "New client connected" ) ;
114+
98115 socket . on ( "joinRoom" , ( roomId ) => {
99116 socket . join ( roomId ) ;
117+ console . log ( `Client joined room: ${ roomId } ` ) ;
100118 } ) ;
101119
102120 socket . on (
@@ -122,11 +140,47 @@ io.on("connection", (socket) => {
122140 ) ;
123141
124142 socket . on ( "disconnect" , ( ) => {
125- console . log ( "User disconnected" ) ;
143+ console . log ( "Client disconnected" ) ;
144+ } ) ;
145+
146+ // Error handling for socket
147+ socket . on ( "error" , ( error ) => {
148+ console . error ( "Socket error:" , error ) ;
126149 } ) ;
127150} ) ;
128151
152+ // Global error handler
153+ app . use ( ( err , req , res , next ) => {
154+ console . error ( err . stack ) ;
155+ res . status ( 500 ) . send ( "Something broke!" ) ;
156+ } ) ;
157+
129158// Start the server
130159server . listen ( PORT , ( ) => {
131160 console . log ( `Server running on port ${ PORT } ` ) ;
161+ console . log ( `Environment: ${ process . env . NODE_ENV } ` ) ;
162+ console . log (
163+ `Static files being served from: ${ path . join ( __dirname , "public" ) } `
164+ ) ;
165+ } ) ;
166+
167+ // Handle server shutdown gracefully
168+ process . on ( "SIGTERM" , ( ) => {
169+ console . log ( "SIGTERM signal received: closing HTTP server" ) ;
170+ server . close ( ( ) => {
171+ console . log ( "HTTP server closed" ) ;
172+ process . exit ( 0 ) ;
173+ } ) ;
132174} ) ;
175+
176+ process . on ( "uncaughtException" , ( err ) => {
177+ console . error ( "Uncaught Exception:" , err ) ;
178+ process . exit ( 1 ) ;
179+ } ) ;
180+
181+ process . on ( "unhandledRejection" , ( reason , promise ) => {
182+ console . error ( "Unhandled Rejection at:" , promise , "reason:" , reason ) ;
183+ // Handle the error appropriately
184+ } ) ;
185+
186+ export default server ;
0 commit comments