Actualizar server.js

This commit is contained in:
2026-02-20 14:31:09 +00:00
parent a8bbd6c5ca
commit c7ae35e941

View File

@@ -253,6 +253,11 @@ async function autoUpdateDB() {
ALTER TABLE scraped_services ADD COLUMN is_urgent BOOLEAN DEFAULT FALSE;
END IF;
-- AÑADIDO: Columna de palabras clave IA para los gremios
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='guilds' AND column_name='ia_keywords') THEN
ALTER TABLE guilds ADD COLUMN ia_keywords JSONB DEFAULT '[]';
END IF;
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='services' AND column_name='client_id') THEN ALTER TABLE services ADD COLUMN client_id INT REFERENCES clients(id) ON DELETE SET NULL; END IF;
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='services' AND column_name='status_id') THEN ALTER TABLE services ADD COLUMN status_id INT REFERENCES service_statuses(id) ON DELETE SET NULL; END IF;
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='services' AND column_name='contact_phone') THEN ALTER TABLE services ADD COLUMN contact_phone TEXT; END IF;
@@ -1027,9 +1032,56 @@ app.delete("/admin/users/:id", authMiddleware, async (req, res) => { try { await
app.get("/config/company", authMiddleware, async (req, res) => { try { const q = await pool.query("SELECT company_slug, full_name, plan_tier FROM users WHERE id=$1", [req.user.accountId]); res.json({ ok: true, slug: q.rows[0]?.company_slug, name: q.rows[0]?.full_name, plan: q.rows[0]?.plan_tier }); } catch (e) { res.status(500).json({ ok: false }); } });
app.post("/config/company", authMiddleware, async (req, res) => { const client = await pool.connect(); try { const { slug } = req.body; if (!slug || slug.length < 3) return res.status(400).json({ ok: false, error: "Mínimo 3 caracteres" }); const cleanSlug = slug.toLowerCase().replace(/[^a-z0-9-]/g, ""); if (cleanSlug !== slug) return res.status(400).json({ ok: false, error: "Carácteres inválidos" }); const check = await client.query("SELECT id FROM users WHERE company_slug=$1 AND id != $2", [cleanSlug, req.user.accountId]); if (check.rowCount > 0) return res.status(400).json({ ok: false, error: "Nombre en uso" }); await client.query("UPDATE users SET company_slug=$1 WHERE id=$2", [cleanSlug, req.user.accountId]); res.json({ ok: true, fullUrl: `https://${cleanSlug}.integrarepara.es` }); } catch (e) { res.status(500).json({ ok: false }); } finally { client.release(); } });
app.get("/guilds", authMiddleware, async (req, res) => { try { const q = await pool.query("SELECT * FROM guilds WHERE owner_id=$1 ORDER BY name ASC", [req.user.accountId]); res.json({ ok: true, guilds: q.rows }); } catch (e) { res.status(500).json({ ok: false }); } });
app.post("/guilds", authMiddleware, async (req, res) => { try { const { name } = req.body; await pool.query("INSERT INTO guilds (name, owner_id) VALUES ($1, $2)", [name, req.user.accountId]); res.json({ ok: true }); } catch (e) { res.status(500).json({ ok: false }); } });
app.delete("/guilds/:id", authMiddleware, async (req, res) => { try { await pool.query("DELETE FROM guilds WHERE id=$1 AND owner_id=$2", [req.params.id, req.user.accountId]); res.json({ ok: true }); } catch (e) { res.status(500).json({ ok: false }); } });
// ==========================================
// 🛠️ RUTAS DE GREMIOS E INTELIGENCIA ARTIFICIAL
// ==========================================
app.get("/guilds", authMiddleware, async (req, res) => {
try {
// AHORA DEVOLVEMOS TAMBIÉN LAS PALABRAS CLAVE
const q = await pool.query("SELECT id, name, ia_keywords FROM guilds WHERE owner_id=$1 ORDER BY name ASC", [req.user.accountId]);
res.json({ ok: true, guilds: q.rows });
} catch (e) {
res.status(500).json({ ok: false });
}
});
app.post("/guilds", authMiddleware, async (req, res) => {
try {
const { name } = req.body;
await pool.query("INSERT INTO guilds (name, owner_id) VALUES ($1, $2)", [name, req.user.accountId]);
res.json({ ok: true });
} catch (e) { res.status(500).json({ ok: false }); }
});
app.delete("/guilds/:id", authMiddleware, async (req, res) => {
try {
await pool.query("DELETE FROM guilds WHERE id=$1 AND owner_id=$2", [req.params.id, req.user.accountId]);
res.json({ ok: true });
} catch (e) { res.status(500).json({ ok: false }); }
});
// NUEVA RUTA: PARA GUARDAR LAS PALABRAS CLAVE DE LA IA
app.put("/guilds/:id/ia-rules", authMiddleware, async (req, res) => {
try {
const { keywords } = req.body; // Viene un array ["grifo", "fuga"]
const guildId = req.params.id;
// Asegurarnos de que el array es válido
const safeKeywords = Array.isArray(keywords) ? keywords : [];
await pool.query(
"UPDATE guilds SET ia_keywords = $1 WHERE id = $2 AND owner_id = $3",
[JSON.stringify(safeKeywords), guildId, req.user.accountId]
);
res.json({ ok: true });
} catch (e) {
console.error("Error guardando IA:", e);
res.status(500).json({ ok: false, error: e.message });
}
});
app.get("/services", authMiddleware, async (req, res) => { try { const q = await pool.query(`SELECT s.*, st.name as status_name, st.color as status_color, c.name as company_name, g.name as guild_name, u.full_name as assigned_name FROM services s LEFT JOIN service_statuses st ON s.status_id = st.id LEFT JOIN companies c ON s.company_id = c.id LEFT JOIN guilds g ON s.guild_id = g.id LEFT JOIN users u ON s.assigned_to = u.id WHERE s.owner_id=$1 ORDER BY s.created_at DESC`, [req.user.accountId]); res.json({ ok: true, services: q.rows }); } catch (e) { res.status(500).json({ ok: false }); } });
app.get("/services/:id", authMiddleware, async (req, res) => { try { const q = await pool.query(`SELECT * FROM services WHERE id=$1 AND owner_id=$2`, [req.params.id, req.user.accountId]); res.json({ ok: true, service: q.rows[0] }); } catch (e) { res.status(500).json({ ok: false }); } });