Files
LogiFlow/server/index.production.ts
T
michaelschal 1745e73b52 Resolve production errors and improve system stability and reliability
Fix critical production errors, including Bad Gateway issues and TypeScript compilation failures, by implementing comprehensive route registration, correcting service configurations, and ensuring production build success.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 7c468936-2a88-4686-ac0a-84921a45222d
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/7c468936-2a88-4686-ac0a-84921a45222d/cH9Kvea
2025-08-13 13:00:39 +00:00

152 lines
5.1 KiB
TypeScript

import express, { type Express, type Request, type Response, type NextFunction } from "express";
import { createServer, type Server } from "http";
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
// Database will be configured in storage.js
import { storage } from "./storage.js";
import { setupLocalAuth, requireAuth } from "./localAuth.production.js";
// Get directory paths
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
console.log('🐳 PRODUCTION: Starting LogiFlow application');
// Force production mode and PostgreSQL storage when deployed in Docker
process.env.NODE_ENV = 'production';
console.log('🐳 Environment:', {
NODE_ENV: process.env.NODE_ENV,
DATABASE_URL: process.env.DATABASE_URL ? 'Present' : 'Missing',
PORT: process.env.PORT
});
const app = express();
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: false, limit: '10mb' }));
app.use((req, res, next) => {
const start = Date.now();
res.on("finish", () => {
const duration = Date.now() - start;
if (req.path.startsWith("/api")) {
console.log(`${req.method} ${req.path} ${res.statusCode} in ${duration}ms`);
}
});
next();
});
// Import all routes for production
import { registerRoutes } from "./routes.js";
async function registerProductionRoutes(app: Express): Promise<Server> {
console.log('🔧 Registering all production routes...');
// Register ALL API routes (same as development)
const server = await registerRoutes(app);
console.log('✅ All routes registered successfully for production');
// Additional health check endpoint for production monitoring
app.get('/api/health', (req: Request, res: Response) => {
res.status(200).json({
status: 'healthy',
timestamp: new Date().toISOString(),
environment: 'production',
database: 'connected',
port: process.env.PORT || 3000,
publicPath: join(__dirname, 'public')
});
});
// Emergency admin reset endpoint (production only)
app.post('/api/emergency-admin-reset', async (req: Request, res: Response) => {
try {
const { secret } = req.body;
// Require emergency secret
const emergencySecret = process.env.EMERGENCY_SECRET || 'logiflow-admin-reset-2025';
if (secret !== emergencySecret) {
return res.status(403).json({ error: 'Invalid emergency secret' });
}
console.log('🚨 EMERGENCY: Admin password reset requested');
// Find and reset admin
const existingAdmin = await storage.getUserByUsername('admin');
if (existingAdmin) {
const { hashPasswordSimple } = await import('./localAuth.production.js');
const newPassword = await hashPasswordSimple('admin');
await storage.updateUser(existingAdmin.id, {
password: newPassword,
passwordChanged: false
});
console.log('✅ EMERGENCY: Admin password reset to admin/admin');
return res.json({
success: true,
message: 'Admin password reset to admin/admin',
adminId: existingAdmin.id
});
} else {
return res.status(404).json({ error: 'Admin user not found' });
}
} catch (error) {
console.error('❌ EMERGENCY: Admin reset failed:', error);
return res.status(500).json({ error: 'Reset failed', details: (error as Error).message });
}
});
// Pas besoin de setupLocalAuth ici car registerRoutes le fait déjà
const server = createServer(app);
return server;
}
const server = await registerProductionRoutes(app);
app.use((err: any, _req: Request, res: Response, _next: NextFunction) => {
const status = err.status || err.statusCode || 500;
const message = err.message || "Internal Server Error";
console.error('Server error:', { status, message, error: err });
res.status(status).json({ message });
throw err;
});
// Serve static files directly in production (no Vite)
const publicPath = join(__dirname, 'public');
console.log('🐳 Serving static files from:', publicPath);
app.use('/assets', express.static(join(publicPath, 'assets')));
app.use('/', express.static(publicPath));
// Add explicit root route handler
app.get('/', (req, res) => {
console.log('🏠 ROOT: Serving index.html for root request');
res.sendFile(join(publicPath, 'index.html'), (err) => {
if (err) {
console.error('❌ ROOT: Error serving index.html:', err);
res.status(500).send('Error loading application');
}
});
});
// SPA fallback - serve index.html for all non-API routes
app.get('*', (req, res, next) => {
if (req.path.startsWith('/api/')) {
return next();
}
console.log(`📄 SPA: Serving index.html for ${req.path}`);
res.sendFile(join(publicPath, 'index.html'), (err) => {
if (err) {
console.error(`❌ SPA: Error serving index.html for ${req.path}:`, err);
res.status(500).send('Error loading application');
}
});
});
const port = process.env.PORT ? parseInt(process.env.PORT) : 3000;
server.listen(port, "0.0.0.0", () => {
console.log(`🐳 PRODUCTION: LogiFlow serving on port ${port}`);
});