Initial commit
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
const express = require('express');
|
||||
const { authRequired } = require('../middleware/auth');
|
||||
const { requireRole } = require('../middleware/rbac');
|
||||
const { getCentralPool } = require('../db/central');
|
||||
const { provisionTenant } = require('../services/tenantProvision');
|
||||
const { getTenantPool } = require('../db/tenant');
|
||||
const { hashPassword } = require('../utils/password');
|
||||
const { getParticipationSummary } = require('../services/participationService');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/companies', authRequired, requireRole('superadmin'), async (req, res, next) => {
|
||||
try {
|
||||
const central = getCentralPool();
|
||||
const [rows] = await central.query('SELECT id, name, code, status, start_date, end_date, db_host, db_port, db_name, created_at FROM companies ORDER BY id DESC');
|
||||
res.json(rows);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/companies', authRequired, requireRole('superadmin'), async (req, res, next) => {
|
||||
try {
|
||||
const { name, code, start_date, end_date, db_name, db_host, db_port, db_user, db_pass, admin_name, admin_email, admin_password } = req.body;
|
||||
if (!name || !code || !db_name || !db_host || !db_user || !db_pass || !admin_name || !admin_email || !admin_password) {
|
||||
return res.status(400).json({ error: 'Faltan campos requeridos' });
|
||||
}
|
||||
if (!start_date || !end_date) {
|
||||
return res.status(400).json({ error: 'Fecha inicio y fin son obligatorias' });
|
||||
}
|
||||
if (start_date > end_date) {
|
||||
return res.status(400).json({ error: 'Fecha inicio no puede ser mayor que fecha fin' });
|
||||
}
|
||||
|
||||
await provisionTenant({
|
||||
name,
|
||||
code,
|
||||
dbName: db_name,
|
||||
dbHost: db_host,
|
||||
dbPort: db_port || 3306,
|
||||
dbUser: db_user,
|
||||
dbPass: db_pass,
|
||||
adminName: admin_name,
|
||||
adminEmail: admin_email,
|
||||
adminPassword: admin_password,
|
||||
startDate: start_date,
|
||||
endDate: end_date
|
||||
});
|
||||
|
||||
res.json({ ok: true });
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
router.patch('/companies/:id/status', authRequired, requireRole('superadmin'), async (req, res, next) => {
|
||||
try {
|
||||
const { status } = req.body;
|
||||
if (!['active', 'suspended'].includes(status)) {
|
||||
return res.status(400).json({ error: 'Estado inválido' });
|
||||
}
|
||||
const central = getCentralPool();
|
||||
await central.query('UPDATE companies SET status = ? WHERE id = ?', [status, req.params.id]);
|
||||
res.json({ ok: true });
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
router.patch('/companies/:id/dates', authRequired, requireRole('superadmin'), async (req, res, next) => {
|
||||
try {
|
||||
const { start_date, end_date } = req.body;
|
||||
if (!start_date || !end_date) {
|
||||
return res.status(400).json({ error: 'Fecha inicio y fin son obligatorias' });
|
||||
}
|
||||
if (start_date > end_date) {
|
||||
return res.status(400).json({ error: 'Fecha inicio no puede ser mayor que fecha fin' });
|
||||
}
|
||||
const central = getCentralPool();
|
||||
await central.query('UPDATE companies SET start_date = ?, end_date = ? WHERE id = ?', [
|
||||
start_date || null,
|
||||
end_date || null,
|
||||
req.params.id
|
||||
]);
|
||||
res.json({ ok: true });
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/companies/:id/participation', authRequired, requireRole('superadmin'), async (req, res, next) => {
|
||||
try {
|
||||
const central = getCentralPool();
|
||||
const [[company]] = await central.query('SELECT * FROM companies WHERE id = ?', [req.params.id]);
|
||||
if (!company) return res.status(404).json({ error: 'Empresa no encontrada' });
|
||||
const tenantPool = getTenantPool(company);
|
||||
const participation = await getParticipationSummary(tenantPool);
|
||||
res.json({ company_id: company.id, participation });
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/companies/:id', authRequired, requireRole('superadmin'), async (req, res, next) => {
|
||||
try {
|
||||
const central = getCentralPool();
|
||||
const [[company]] = await central.query('SELECT * FROM companies WHERE id = ?', [req.params.id]);
|
||||
if (!company) return res.status(404).json({ error: 'Empresa no encontrada' });
|
||||
|
||||
const tenantPool = getTenantPool(company);
|
||||
const [[{ periods }]] = await tenantPool.query('SELECT COUNT(*) AS periods FROM survey_periods');
|
||||
const [[{ responses }]] = await tenantPool.query('SELECT COUNT(*) AS responses FROM responses');
|
||||
|
||||
if (periods > 0 || responses > 0) {
|
||||
return res.status(400).json({ error: 'No se puede eliminar: existen encuestas registradas' });
|
||||
}
|
||||
|
||||
await central.query('DROP DATABASE IF EXISTS `' + company.db_name + '`');
|
||||
await central.query('DELETE FROM companies WHERE id = ?', [company.id]);
|
||||
res.json({ ok: true });
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/companies/:id/admins', authRequired, requireRole('superadmin'), async (req, res, next) => {
|
||||
try {
|
||||
const { name, email, password } = req.body;
|
||||
if (!name || !email || !password) {
|
||||
return res.status(400).json({ error: 'Nombre, email y password requeridos' });
|
||||
}
|
||||
const central = getCentralPool();
|
||||
const [[company]] = await central.query('SELECT * FROM companies WHERE id = ?', [req.params.id]);
|
||||
if (!company) return res.status(404).json({ error: 'Empresa no encontrada' });
|
||||
|
||||
const tenantPool = getTenantPool(company);
|
||||
const passwordHash = await hashPassword(password);
|
||||
await tenantPool.query(
|
||||
'INSERT INTO admins (name, email, password_hash, role, status) VALUES (?, ?, ?, "admin", "active")',
|
||||
[name, email, passwordHash]
|
||||
);
|
||||
res.json({ ok: true });
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/companies/:id/admins', authRequired, requireRole('superadmin'), async (req, res, next) => {
|
||||
try {
|
||||
const central = getCentralPool();
|
||||
const [[company]] = await central.query('SELECT * FROM companies WHERE id = ?', [req.params.id]);
|
||||
if (!company) return res.status(404).json({ error: 'Empresa no encontrada' });
|
||||
|
||||
const tenantPool = getTenantPool(company);
|
||||
const [rows] = await tenantPool.query('SELECT id, name, email, status, created_at FROM admins ORDER BY id DESC');
|
||||
res.json(rows);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
router.patch('/companies/:id/admins/:adminId/status', authRequired, requireRole('superadmin'), async (req, res, next) => {
|
||||
try {
|
||||
const { status } = req.body;
|
||||
if (!['active', 'inactive'].includes(status)) {
|
||||
return res.status(400).json({ error: 'Estado inválido' });
|
||||
}
|
||||
const central = getCentralPool();
|
||||
const [[company]] = await central.query('SELECT * FROM companies WHERE id = ?', [req.params.id]);
|
||||
if (!company) return res.status(404).json({ error: 'Empresa no encontrada' });
|
||||
|
||||
const tenantPool = getTenantPool(company);
|
||||
await tenantPool.query('UPDATE admins SET status = ? WHERE id = ?', [status, req.params.adminId]);
|
||||
res.json({ ok: true });
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user