diff --git a/server/build-production.sh b/server/build-production.sh index e1d01fa..75a6d8b 100755 --- a/server/build-production.sh +++ b/server/build-production.sh @@ -37,6 +37,16 @@ if [ ! -f "package.json" ]; then exit 1 fi +if [ -f "../package.json" ]; then + print_info "Build frontend..." + cd .. + npm ci + npm run build + cd server +else + print_warning "package.json frontend non trovato, salto build frontend" +fi + # Verifica che esista tsconfig.json if [ ! -f "tsconfig.json" ]; then print_error "File tsconfig.json non trovato!" @@ -79,6 +89,15 @@ if [ -d "static" ]; then print_info "File statici copiati in dist/static" fi +if [ -d "../dist" ] && [ -f "../dist/index.html" ]; then + rm -rf dist/frontend + mkdir -p dist/frontend + cp -r ../dist/* dist/frontend/ + print_info "Frontend copiato in dist/frontend" +else + print_warning "Build frontend non trovato in ../dist, salto copia" +fi + # Crea file package.json per produzione (solo dipendenze runtime) print_info "Creazione package.json per produzione..." node -e " @@ -108,4 +127,4 @@ print_info "🚀 Per avviare il server: cd dist && npm start" print_info "📊 Dimensione build:" du -sh dist/ -print_success "🎉 Server pronto per il deployment in produzione!" \ No newline at end of file +print_success "🎉 Server pronto per il deployment in produzione!" diff --git a/server/src/index.ts b/server/src/index.ts index dee515a..6d4de31 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -150,13 +150,51 @@ const swaggerOptions = { const swaggerSpec = swaggerJsdoc(swaggerOptions); ELKService.info('Swagger specification generated'); +const resolveDirWithFile = (candidates: string[], requiredFile: string): string | null => { + for (const candidate of candidates) { + try { + const filePath = path.join(candidate, requiredFile); + if (fs.existsSync(filePath)) return candidate; + } catch { + // ignore + } + } + return null; +}; + +const frontendDistDir = resolveDirWithFile( + [ + path.resolve(__dirname, './frontend'), + path.resolve(__dirname, '../../dist'), + path.resolve(process.cwd(), 'dist'), + path.resolve(process.cwd(), '../dist'), + ], + 'index.html' +); + +const staticDir = resolveDirWithFile( + [ + path.resolve(__dirname, './static'), + path.resolve(__dirname, '../static'), + ], + '' +); + // Serve static files for PDF reports -app.use('/static', express.static(path.join(__dirname, '../static'))); -ELKService.info('Static files middleware enabled for /static'); +if (staticDir) { + app.use('/static', express.static(staticDir)); + ELKService.info(`Static files middleware enabled for /static (${staticDir})`); +} else { + ELKService.warn('Static files directory not found; /static will not be served'); +} // Serve frontend build files -app.use(express.static(path.join(__dirname, '../../dist'))); -ELKService.info('Frontend static files middleware enabled for /dist'); +if (frontendDistDir) { + app.use(express.static(frontendDistDir)); + ELKService.info(`Frontend static files middleware enabled (${frontendDistDir})`); +} else { + ELKService.warn('Frontend dist directory not found; frontend will not be served'); +} // Routes app.use('/api', routes); @@ -190,7 +228,11 @@ app.use('/api', (req, res) => { // Catch-all handler for React Router (must be after API routes) app.get('*', (req, res) => { - res.sendFile(path.join(__dirname, '../../dist/index.html')); + if (!frontendDistDir) { + res.status(404).send('Frontend not available'); + return; + } + res.sendFile(path.join(frontendDistDir, 'index.html')); }); ELKService.info('Catch-all route registered for React Router');