Actualizar server.js
This commit is contained in:
47
server.js
47
server.js
@@ -36,7 +36,6 @@ async function autoUpdateDB() {
|
|||||||
try {
|
try {
|
||||||
console.log("🔄 Verificando estructura DB...");
|
console.log("🔄 Verificando estructura DB...");
|
||||||
|
|
||||||
// TABLAS PRINCIPALES (Usuarios, Clientes, Gremios...)
|
|
||||||
await client.query(`
|
await client.query(`
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
@@ -101,10 +100,7 @@ async function autoUpdateDB() {
|
|||||||
is_final BOOLEAN DEFAULT FALSE,
|
is_final BOOLEAN DEFAULT FALSE,
|
||||||
created_at TIMESTAMP DEFAULT NOW()
|
created_at TIMESTAMP DEFAULT NOW()
|
||||||
);
|
);
|
||||||
`);
|
|
||||||
|
|
||||||
// TABLAS DE ZONAS (Versión simplificada, sin pueblos)
|
|
||||||
await client.query(`
|
|
||||||
CREATE TABLE IF NOT EXISTS zones (
|
CREATE TABLE IF NOT EXISTS zones (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
@@ -116,10 +112,7 @@ async function autoUpdateDB() {
|
|||||||
zone_id INT REFERENCES zones(id) ON DELETE CASCADE,
|
zone_id INT REFERENCES zones(id) ON DELETE CASCADE,
|
||||||
PRIMARY KEY (user_id, zone_id)
|
PRIMARY KEY (user_id, zone_id)
|
||||||
);
|
);
|
||||||
`);
|
|
||||||
|
|
||||||
// TABLA SERVICIOS
|
|
||||||
await client.query(`
|
|
||||||
CREATE TABLE IF NOT EXISTS services (
|
CREATE TABLE IF NOT EXISTS services (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
owner_id INT REFERENCES users(id) ON DELETE CASCADE,
|
owner_id INT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
@@ -156,7 +149,7 @@ async function autoUpdateDB() {
|
|||||||
);
|
);
|
||||||
`);
|
`);
|
||||||
|
|
||||||
// PARCHE DE REPARACIÓN (Mantenido por seguridad)
|
// PARCHE REPARACIÓN
|
||||||
await client.query(`
|
await client.query(`
|
||||||
DO $$ BEGIN
|
DO $$ BEGIN
|
||||||
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='client_id') THEN ALTER TABLE services ADD COLUMN client_id INT REFERENCES clients(id) ON DELETE SET NULL; END IF;
|
||||||
@@ -204,12 +197,11 @@ app.post("/auth/reset-password", async (req, res) => { const client = await pool
|
|||||||
|
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// 🛠️ GESTIÓN DE ESTADOS (CRUD COMPLETO)
|
// 🛠️ GESTIÓN DE ESTADOS (CRUD SEGURO)
|
||||||
// ==========================================
|
// ==========================================
|
||||||
app.get("/statuses", authMiddleware, async (req, res) => {
|
app.get("/statuses", authMiddleware, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
let q = await pool.query("SELECT * FROM service_statuses WHERE owner_id=$1 ORDER BY id ASC", [req.user.accountId]);
|
let q = await pool.query("SELECT * FROM service_statuses WHERE owner_id=$1 ORDER BY id ASC", [req.user.accountId]);
|
||||||
// Si no hay estados, crea los default
|
|
||||||
if (q.rowCount === 0) {
|
if (q.rowCount === 0) {
|
||||||
const defaults = [{name:'Pendiente',c:'gray',d:true,f:false},{name:'En Proceso',c:'blue',d:false,f:false},{name:'Terminado',c:'green',d:false,f:true},{name:'Cancelado',c:'red',d:false,f:true}];
|
const defaults = [{name:'Pendiente',c:'gray',d:true,f:false},{name:'En Proceso',c:'blue',d:false,f:false},{name:'Terminado',c:'green',d:false,f:true},{name:'Cancelado',c:'red',d:false,f:true}];
|
||||||
for (const s of defaults) await pool.query("INSERT INTO service_statuses (owner_id,name,color,is_default,is_final) VALUES ($1,$2,$3,$4,$5)", [req.user.accountId,s.name,s.c,s.d,s.f]);
|
for (const s of defaults) await pool.query("INSERT INTO service_statuses (owner_id,name,color,is_default,is_final) VALUES ($1,$2,$3,$4,$5)", [req.user.accountId,s.name,s.c,s.d,s.f]);
|
||||||
@@ -219,7 +211,6 @@ app.get("/statuses", authMiddleware, async (req, res) => {
|
|||||||
} catch (e) { res.status(500).json({ ok: false }); }
|
} catch (e) { res.status(500).json({ ok: false }); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// NUEVO: CREAR ESTADO
|
|
||||||
app.post("/statuses", authMiddleware, async (req, res) => {
|
app.post("/statuses", authMiddleware, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { name, color } = req.body;
|
const { name, color } = req.body;
|
||||||
@@ -229,12 +220,38 @@ app.post("/statuses", authMiddleware, async (req, res) => {
|
|||||||
} catch(e) { res.status(500).json({ ok: false }); }
|
} catch(e) { res.status(500).json({ ok: false }); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// NUEVO: BORRAR ESTADO
|
// 🔥 BORRADO SEGURO DE ESTADOS 🔥
|
||||||
app.delete("/statuses/:id", authMiddleware, async (req, res) => {
|
app.delete("/statuses/:id", authMiddleware, async (req, res) => {
|
||||||
|
const client = await pool.connect();
|
||||||
try {
|
try {
|
||||||
await pool.query("DELETE FROM service_statuses WHERE id=$1 AND owner_id=$2", [req.params.id, req.user.accountId]);
|
const statusId = req.params.id;
|
||||||
|
const accountId = req.user.accountId;
|
||||||
|
|
||||||
|
// 1. Comprobar si hay servicios usando este estado
|
||||||
|
const check = await client.query("SELECT COUNT(*) FROM services WHERE status_id = $1 AND owner_id = $2", [statusId, accountId]);
|
||||||
|
const usageCount = parseInt(check.rows[0].count);
|
||||||
|
|
||||||
|
if (usageCount > 0) {
|
||||||
|
return res.status(400).json({
|
||||||
|
ok: false,
|
||||||
|
error: `No se puede borrar: Este estado se usa en ${usageCount} servicios.`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Si no se usa, borrarlo
|
||||||
|
const del = await client.query("DELETE FROM service_statuses WHERE id=$1 AND owner_id=$2", [statusId, accountId]);
|
||||||
|
|
||||||
|
if (del.rowCount === 0) {
|
||||||
|
return res.status(404).json({ ok: false, error: "Estado no encontrado o no autorizado" });
|
||||||
|
}
|
||||||
|
|
||||||
res.json({ ok: true });
|
res.json({ ok: true });
|
||||||
} catch(e) { res.status(500).json({ ok: false }); }
|
} catch(e) {
|
||||||
|
console.error("Error borrando estado:", e);
|
||||||
|
res.status(500).json({ ok: false, error: "Error interno" });
|
||||||
|
} finally {
|
||||||
|
client.release();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// CLIENTES, COMPAÑIAS, GREMIOS
|
// CLIENTES, COMPAÑIAS, GREMIOS
|
||||||
@@ -245,7 +262,7 @@ app.get("/companies", authMiddleware, async (req, res) => { try { const q = awai
|
|||||||
app.post("/companies", authMiddleware, async (req, res) => { try { const { name } = req.body; await pool.query("INSERT INTO companies (name, owner_id) VALUES ($1, $2)", [name, req.user.accountId]); res.json({ ok: true }); } catch (e) { res.status(500).json({ ok: false }); } });
|
app.post("/companies", authMiddleware, async (req, res) => { try { const { name } = req.body; await pool.query("INSERT INTO companies (name, owner_id) VALUES ($1, $2)", [name, req.user.accountId]); res.json({ ok: true }); } catch (e) { res.status(500).json({ ok: false }); } });
|
||||||
app.delete("/companies/:id", authMiddleware, async (req, res) => { try { await pool.query("DELETE FROM companies 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 }); } });
|
app.delete("/companies/:id", authMiddleware, async (req, res) => { try { await pool.query("DELETE FROM companies 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 }); } });
|
||||||
|
|
||||||
// OBTENER OPERARIOS POR GREMIO
|
// OBTENER OPERARIOS
|
||||||
app.get("/operators", authMiddleware, async (req, res) => {
|
app.get("/operators", authMiddleware, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { guild_id } = req.query;
|
const { guild_id } = req.query;
|
||||||
|
|||||||
Reference in New Issue
Block a user