Actualizar server.js

This commit is contained in:
2026-03-07 15:28:36 +00:00
parent fe8d487f39
commit c19ba7a411

View File

@@ -261,6 +261,19 @@ async function autoUpdateDB() {
);
`);
-- 💬 CHAT Y NOTAS INTERNAS
CREATE TABLE IF NOT EXISTS service_communications (
id SERIAL PRIMARY KEY,
scraped_id INT REFERENCES scraped_services(id) ON DELETE CASCADE,
owner_id INT REFERENCES users(id) ON DELETE CASCADE,
sender_id INT REFERENCES users(id) ON DELETE SET NULL,
sender_name TEXT NOT NULL,
sender_role TEXT,
message TEXT NOT NULL,
is_internal BOOLEAN DEFAULT FALSE, -- Si es TRUE, el operario NO lo ve
created_at TIMESTAMP DEFAULT NOW()
);
// PARCHE DE ACTUALIZACIÓN
await client.query(`
DO $$ BEGIN
@@ -2755,7 +2768,69 @@ app.get("/providers/credentials", authMiddleware, async (req, res) => {
}
});
// ==========================================
// 💬 CHAT Y COMUNICACIÓN INTERNA (TIPO iTRAMIT)
// ==========================================
// 1. Obtener los mensajes de un expediente
app.get("/services/:id/chat", authMiddleware, async (req, res) => {
try {
const { id } = req.params;
const isOperario = req.user.role === 'operario';
// Si es operario, NO puede ver los mensajes marcados como "is_internal = true"
let query = `
SELECT id, sender_id, sender_name, sender_role, message, is_internal, created_at
FROM service_communications
WHERE scraped_id = $1 AND owner_id = $2
`;
if (isOperario) {
query += ` AND is_internal = FALSE`;
}
query += ` ORDER BY created_at ASC`; // Orden cronológico (chat)
const q = await pool.query(query, [id, req.user.accountId]);
res.json({ ok: true, messages: q.rows });
} catch (e) {
console.error("Error cargando chat:", e);
res.status(500).json({ ok: false });
}
});
// 2. Enviar un nuevo mensaje (Oficina u Operario)
app.post("/services/:id/chat", authMiddleware, async (req, res) => {
try {
const { id } = req.params;
const { message, is_internal } = req.body;
if (!message || message.trim() === "") {
return res.status(400).json({ ok: false, error: "El mensaje está vacío" });
}
// Bloqueo de seguridad: Un operario NUNCA puede crear una nota interna oculta
const isOperario = req.user.role === 'operario';
const finalIsInternal = isOperario ? false : (is_internal || false);
// Sacar el nombre y rol del que escribe
const userQ = await pool.query("SELECT full_name, role FROM users WHERE id=$1", [req.user.sub]);
const senderName = userQ.rows[0]?.full_name || "Usuario Desconocido";
const senderRole = userQ.rows[0]?.role || "operario";
// Guardar el mensaje en la base de datos
await pool.query(`
INSERT INTO service_communications
(scraped_id, owner_id, sender_id, sender_name, sender_role, message, is_internal)
VALUES ($1, $2, $3, $4, $5, $6, $7)
`, [id, req.user.accountId, req.user.sub, senderName, senderRole, message.trim(), finalIsInternal]);
res.json({ ok: true });
} catch (e) {
console.error("Error enviando mensaje:", e);
res.status(500).json({ ok: false });
}
});
// ==========================================
// 🕒 EL RELOJ DEL SISTEMA (Ejecutar cada minuto)