/** * LandveX Simple Gateway * * Unifies all backend services without external dependencies. * Uses only Node.js built-in modules. */ const http = require('http'); const url = require('url'); const PORT = process.env.PORT || 3004; // Service registry - only running services const services = { intelligence: { host: 'localhost', port: 3002, path: '/api/v1', status: 'unknown' }, // apollo: { host: 'localhost', port: 3001, path: '/api/apollo', status: 'unknown' }, // ledger: { host: 'localhost', port: 3250, path: '', status: 'unknown' }, // incidents: { host: 'localhost', port: 3303, path: '', status: 'unknown' }, }; // Simple proxy function function proxyRequest(req, res, target) { const options = { hostname: target.host, port: target.port, path: req.url, method: req.method, headers: { ...req.headers, host: `${target.host}:${target.port}`, }, }; const proxyReq = http.request(options, (proxyRes) => { res.writeHead(proxyRes.statusCode, proxyRes.headers); proxyRes.pipe(res); }); proxyReq.on('error', (err) => { console.error(`Proxy error: ${err.message}`); res.statusCode = 502; res.end(JSON.stringify({ error: 'Bad Gateway', message: err.message })); }); req.pipe(proxyReq); } // Health check function async function checkServiceHealth(name, service) { return new Promise((resolve) => { const req = http.request({ hostname: service.host, port: service.port, path: '/health', method: 'GET', timeout: 5000, }, (res) => { service.status = res.statusCode === 200 ? 'healthy' : 'unhealthy'; resolve(); }); req.on('error', () => { service.status = 'down'; resolve(); }); req.on('timeout', () => { service.status = 'timeout'; req.destroy(); resolve(); }); req.end(); }); } // Main server const server = http.createServer((req, res) => { // CORS res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); if (req.method === 'OPTIONS') { res.statusCode = 204; res.end(); return; } // Health check if (req.url === '/health') { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ status: 'ok', version: '0.1.0-gateway', services: Object.entries(services).map(([name, config]) => ({ name, status: config.status, url: `http://${config.host}:${config.port}`, })), })); return; } // Route to appropriate service if (req.url.startsWith('/api/v1')) { proxyRequest(req, res, services.intelligence); } else { res.statusCode = 404; res.end(JSON.stringify({ error: 'Not Found', path: req.url })); } }); // Check health of all services on startup async function init() { console.log('🔍 Checking service health...'); for (const [name, service] of Object.entries(services)) { await checkServiceHealth(name, service); console.log(` ${name}: ${service.status}`); } server.listen(PORT, () => { console.log(`🚀 LandveX Gateway running on port ${PORT}`); console.log(`📡 Services:`); Object.entries(services).forEach(([name, config]) => { console.log(` - ${name}: http://${config.host}:${config.port} (${config.status})`); }); }); } init();