diff --git a/server.js b/server.js index b4f0f7c..f9b86b3 100644 --- a/server.js +++ b/server.js @@ -1796,6 +1796,52 @@ app.get("/ranking", authMiddleware, async (req, res) => { } }); + +// ========================================== +// 📍 MOTOR GPS: RASTREO EN TIEMPO REAL +// ========================================== + +// El operario envía su ubicación +app.post("/services/:id/location", authMiddleware, async (req, res) => { + try { + const { lat, lng } = req.body; + if (!lat || !lng) return res.status(400).json({ ok: false }); + + const locData = { lat, lng, updated_at: new Date().toISOString() }; + + await pool.query(` + UPDATE scraped_services + SET raw_data = jsonb_set(COALESCE(raw_data, '{}'::jsonb), '{worker_location}', $1::jsonb) + WHERE id = $2 AND assigned_to = $3 + `, [JSON.stringify(locData), req.params.id, req.user.sub]); + + res.json({ ok: true }); + } catch (e) { + res.status(500).json({ ok: false }); + } +}); + +// El cliente consulta la ubicación +app.get("/public/portal/:token/location/:serviceId", async (req, res) => { + try { + const { token, serviceId } = req.params; + + // Verificar dueño + const clientQ = await pool.query("SELECT owner_id FROM clients WHERE portal_token = $1", [token]); + if (clientQ.rowCount === 0) return res.status(404).json({ ok: false }); + + // Cargar datos + const serviceQ = await pool.query("SELECT raw_data FROM scraped_services WHERE id = $1 AND owner_id = $2", [serviceId, clientQ.rows[0].owner_id]); + if (serviceQ.rowCount === 0) return res.status(404).json({ ok: false }); + + const loc = serviceQ.rows[0].raw_data.worker_location || null; + res.json({ ok: true, location: loc }); + } catch (e) { + res.status(500).json({ ok: false }); + } +}); + + // ========================================== // 🕒 EL RELOJ DEL SISTEMA (Ejecutar cada minuto) // ==========================================