const express = require('express'); const { spawn } = require('child_process'); const fs = require('fs'); const path = require('path'); const app = express(); const port = 3005; // Port for the GTM Architect service app.use(express.json({ limit: '50mb' })); // Determine Environment and Paths const distPath = path.join(__dirname, 'dist'); const isProduction = fs.existsSync(distPath); const staticDir = isProduction ? distPath : __dirname; console.log(`[Init] Serving static files from: ${staticDir}`); app.use(express.static(staticDir)); // Determine Python Script Path // In Docker (optimized), script is in same dir. Locally, it might be one level up. let pythonScriptPath = path.join(__dirname, 'gtm_architect_orchestrator.py'); if (!fs.existsSync(pythonScriptPath)) { pythonScriptPath = path.join(__dirname, '../gtm_architect_orchestrator.py'); } console.log(`[Init] Using Python script at: ${pythonScriptPath}`); function callPythonScript(mode, data, res) { const pythonProcess = spawn('python3', [pythonScriptPath, '--mode', mode]); let pythonData = ''; let errorData = ''; pythonProcess.stdout.on('data', (data) => { pythonData += data.toString(); }); pythonProcess.stderr.on('data', (data) => { errorData += data.toString(); }); pythonProcess.on('close', (code) => { if (code !== 0) { console.error(`Python script exited with code ${code}`); console.error('Stderr:', errorData); return res.status(500).json({ error: 'Python script execution failed.', details: errorData }); } try { const result = JSON.parse(pythonData); res.json(result); } catch (e) { console.error('Failed to parse Python script output:', e); console.error('Raw output:', pythonData); res.status(500).json({ error: 'Failed to parse Python script output.', details: pythonData }); } }); pythonProcess.stdin.write(JSON.stringify(data)); pythonProcess.stdin.end(); } // API endpoint to handle requests from the frontend app.post('/api/gtm', (req, res) => { const { mode, data } = req.body; if (!mode || !data) { return res.status(400).json({ error: 'Missing mode or data in request body' }); } callPythonScript(mode, data, res); }); // Serve the main index.html for any other requests to support client-side routing app.get('*', (req, res) => { res.sendFile(path.join(staticDir, 'index.html')); }); const server = app.listen(port, () => { console.log(`GTM Architect server listening at http://localhost:${port} (Timeout: 600s)`); }); // Prevent 502 Bad Gateway by increasing Node.js server timeouts to match Nginx server.setTimeout(600000); server.keepAliveTimeout = 610000; server.headersTimeout = 620000;