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 }); }); // ── 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}`); });