require('dotenv').config(); const express = require('express'); const { createServer } = require('http'); const { Server } = require('socket.io'); const app = express(); const httpServer = createServer(app); const io = new Server(httpServer, { cors: { origin: '*' } }); app.use(express.json()); // ── /emit ───────────────────────────────────────────────────────────────────── // PHP calls this after any significant action. // Body: { event, data, company_id } // app.post('/emit', (req, res) => { const secret = req.headers['x-emit-secret']; if (secret !== process.env.EMIT_SECRET) { return res.status(403).json({ ok: false, message: 'Forbidden' }); } const { event, data, company_id } = req.body; if (!event || !company_id) { return res.status(400).json({ ok: false, message: 'event and company_id required' }); } // Broadcast only to the room for this company io.to(`company_${company_id}`).emit(event, data); console.log(`[emit] company=${company_id} event=${event}`, data); res.json({ ok: true }); }); // ── /health ─────────────────────────────────────────────────────────────────── app.get('/health', (req, res) => { res.json({ status: 'ok', uptime: Math.floor(process.uptime()), connections: io.engine.clientsCount, memory_mb: Math.round(process.memoryUsage().rss / 1024 / 1024 * 10) / 10 }); }); // ── WebSocket connections ───────────────────────────────────────────────────── // Each browser tab connects here on page load. // It joins a room named company_ so events stay isolated per company. // io.on('connection', (socket) => { const company_id = socket.handshake.query.company_id; if (!company_id) { socket.disconnect(); return; } socket.join(`company_${company_id}`); console.log(`[connect] socket=${socket.id} company=${company_id}`); socket.on('disconnect', () => { console.log(`[disconnect] socket=${socket.id}`); }); }); // ── Start ───────────────────────────────────────────────────────────────────── const PORT = process.env.PORT || 3000; httpServer.listen(PORT, () => { console.log(`Node.js real-time server running on port ${PORT}`); });