Actualizar server.js

This commit is contained in:
2026-02-27 21:24:14 +00:00
parent dbeb6304ed
commit 60951c76d7

View File

@@ -1872,25 +1872,37 @@ app.get("/public/assignment/:token", async (req, res) => {
} }
if (new Date() > new Date(assign.expires_at)) { if (new Date() > new Date(assign.expires_at)) {
// Lo marcamos como expirado si ya pasó el tiempo
await pool.query("UPDATE assignment_pings SET status = 'expired' WHERE id = $1", [assign.id]); await pool.query("UPDATE assignment_pings SET status = 'expired' WHERE id = $1", [assign.id]);
return res.json({ ok: false, error: "El tiempo para aceptar este aviso ha caducado." }); return res.json({ ok: false, error: "El tiempo para aceptar este aviso ha caducado." });
} }
res.json({ ok: true, assignment: assign }); // Parsear datos para enviarlos bonitos a la pantalla de aceptar.html
const raw = assign.raw_data || {};
const serviceData = {
"Gremio": raw["Gremio"] || raw.guild_name || "Servicio General",
"Expediente": assign.service_ref || raw["Referencia"] || "Sin Ref",
"Población": raw["Población"] || raw["POBLACION-PROVINCIA"] || "",
"Código Postal": raw["Código Postal"] || "",
"Descripción": raw["Descripción"] || raw["DESCRIPCION"] || "Revisar en el lugar."
};
res.json({ ok: true, service: serviceData, debug: { hora_limite_bd: assign.expires_at } });
} catch (e) { } catch (e) {
console.error("Error al obtener asignación:", e); console.error("Error al obtener asignación:", e);
res.status(500).json({ ok: false }); res.status(500).json({ ok: false });
} }
}); });
app.post("/public/assignment/:token/accept", async (req, res) => { app.post("/public/assignment/respond", async (req, res) => {
const client = await pool.connect(); const client = await pool.connect();
try { try {
const { token } = req.params; const { token, action } = req.body;
if (!token || !action) return res.status(400).json({ ok: false, error: "Faltan datos" });
await client.query('BEGIN'); await client.query('BEGIN');
// 1. Validar ping bloqueando la fila para evitar dobles clicks // 1. Validar ping bloqueando la fila
const qPing = await client.query("SELECT * FROM assignment_pings WHERE token = $1 AND status = 'pending' FOR UPDATE", [token]); const qPing = await client.query("SELECT * FROM assignment_pings WHERE token = $1 AND status = 'pending' FOR UPDATE", [token]);
if (qPing.rowCount === 0) { if (qPing.rowCount === 0) {
await client.query('ROLLBACK'); await client.query('ROLLBACK');
@@ -1899,38 +1911,50 @@ app.post("/public/assignment/:token/accept", async (req, res) => {
const ping = qPing.rows[0]; const ping = qPing.rows[0];
// 2. Marcar ping como aceptado if (action === 'reject') {
await client.query("UPDATE assignment_pings SET status = 'accepted' WHERE id = $1", [ping.id]); await client.query("UPDATE assignment_pings SET status = 'rejected' WHERE id = $1", [ping.id]);
await client.query('COMMIT');
// 3. Sacar datos del servicio return res.json({ ok: true });
const sQ = await client.query("SELECT owner_id, raw_data FROM scraped_services WHERE id = $1", [ping.scraped_id]);
const ownerId = sQ.rows[0].owner_id;
let rawData = sQ.rows[0].raw_data || {};
// 4. Poner el estado en "Asignado" si existe
const statusQ = await client.query("SELECT id, name FROM service_statuses WHERE owner_id=$1 AND name ILIKE '%asignado%' LIMIT 1", [ownerId]);
const statusAsignadoId = statusQ.rows[0]?.id || null;
if (statusAsignadoId) {
rawData.status_operativo = statusAsignadoId;
} }
// 5. Actualizar el expediente oficial con el técnico if (action === 'accept') {
await client.query(` // 2. Marcar ping como aceptado
UPDATE scraped_services await client.query("UPDATE assignment_pings SET status = 'accepted' WHERE id = $1", [ping.id]);
SET assigned_to = $1, automation_status = 'completed', raw_data = $2
WHERE id = $3
`, [ping.user_id, JSON.stringify(rawData), ping.scraped_id]);
await client.query('COMMIT'); // 3. Sacar datos del servicio
const sQ = await client.query("SELECT owner_id, raw_data FROM scraped_services WHERE id = $1", [ping.scraped_id]);
const ownerId = sQ.rows[0].owner_id;
let rawData = sQ.rows[0].raw_data || {};
// 6. ¡Magia! Le enviamos un WhatsApp automático al cliente diciendo que ya tiene técnico // 4. Poner el estado en "Asignado" si existe
triggerWhatsAppEvent(ownerId, ping.scraped_id, 'wa_evt_assigned').catch(e => console.error(e)); const statusQ = await client.query("SELECT id, name FROM service_statuses WHERE owner_id=$1 AND name ILIKE '%asignado%' LIMIT 1", [ownerId]);
const statusAsignadoId = statusQ.rows[0]?.id || null;
if (statusAsignadoId) {
rawData.status_operativo = statusAsignadoId;
}
// 5. Actualizar el expediente oficial con el técnico
await client.query(`
UPDATE scraped_services
SET assigned_to = $1, automation_status = 'completed', raw_data = $2
WHERE id = $3
`, [ping.user_id, JSON.stringify(rawData), ping.scraped_id]);
await client.query('COMMIT');
// 6. ¡Magia! Le enviamos un WhatsApp automático al cliente diciendo que ya tiene técnico
triggerWhatsAppEvent(ownerId, ping.scraped_id, 'wa_evt_assigned').catch(e => console.error(e));
return res.json({ ok: true });
}
await client.query('ROLLBACK');
res.status(400).json({ ok: false, error: "Acción no válida" });
res.json({ ok: true });
} catch (e) { } catch (e) {
await client.query('ROLLBACK'); await client.query('ROLLBACK');
console.error("Error aceptando asignación:", e); console.error("Error respondiendo asignación:", e);
res.status(500).json({ ok: false, error: "Error interno del servidor" }); res.status(500).json({ ok: false, error: "Error interno del servidor" });
} finally { } finally {
client.release(); client.release();