From a4480664a290e7838a69220d2f30c5ba948c0752 Mon Sep 17 00:00:00 2001 From: marsalva Date: Sun, 15 Feb 2026 19:33:07 +0000 Subject: [PATCH] Actualizar server.js --- server.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/server.js b/server.js index 92f7dac..8938630 100644 --- a/server.js +++ b/server.js @@ -415,6 +415,7 @@ app.post("/providers/automate/:id", authMiddleware, async (req, res) => { }); // Endpoint público para aceptar.html +// 1. Endpoint para que el móvil del operario vea los datos del servicio app.get("/public/assignment/:token", async (req, res) => { try { const { token } = req.params; @@ -425,31 +426,40 @@ app.get("/public/assignment/:token", async (req, res) => { JOIN users u ON ap.user_id = u.id WHERE ap.token = $1 AND ap.status = 'pending' AND ap.expires_at > NOW() `, [token]); - if (q.rowCount === 0) return res.status(404).json({ ok: false, error: "Enlace caducado" }); + + if (q.rowCount === 0) return res.status(404).json({ ok: false, error: "Enlace caducado o ya aceptado" }); + res.json({ ok: true, service: q.rows[0].raw_data, worker: q.rows[0].worker_name }); } catch (e) { res.status(500).json({ ok: false }); } }); -// Endpoint público para respuesta +// 2. Endpoint para procesar el botón de "Aceptar" del móvil app.post("/public/assignment/respond", async (req, res) => { const client = await pool.connect(); try { const { token, action } = req.body; await client.query('BEGIN'); + const q = await client.query("SELECT * FROM assignment_pings WHERE token = $1 AND status = 'pending' AND expires_at > NOW()", [token]); - if (q.rowCount === 0) throw new Error("Acción caducada"); + if (q.rowCount === 0) throw new Error("Turno expirado o ya procesado"); + const ping = q.rows[0]; if (action === 'accept') { + // Marcamos como aceptado await client.query("UPDATE assignment_pings SET status = 'accepted' WHERE id = $1", [ping.id]); + // Importante: Marcamos el original como completado para que desaparezca de la cola await client.query("UPDATE scraped_services SET status = 'imported', automation_status = 'completed' WHERE id = $1", [ping.scraped_id]); - // (La lógica de traspaso real a 'services' iría aquí, reutilizando handleFinalImport) + + // Aquí llamarías a tu función de crear servicio oficial (POST /services) } else { + // Si rechaza, forzamos expiración para que el reloj salte al siguiente await client.query("UPDATE assignment_pings SET status = 'rejected', expires_at = NOW() WHERE id = $1", [ping.id]); } + await client.query('COMMIT'); res.json({ ok: true }); - } catch (e) { await client.query('ROLLBACK'); res.status(400).json({ ok: false }); } finally { client.release(); } + } catch (e) { await client.query('ROLLBACK'); res.status(400).json({ ok: false, error: e.message }); } finally { client.release(); } }); app.post("/providers/import/:id", authMiddleware, async (req, res) => {