Actualizar server.js
This commit is contained in:
75
server.js
75
server.js
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user