add validation and add pool

This commit is contained in:
2025-05-22 18:33:00 -04:00
parent 81672bef23
commit 7a6986faae
14 changed files with 161 additions and 145 deletions
+18 -10
View File
@@ -1,20 +1,28 @@
const mysql = require('mysql2');
const mysql = require('mysql2/promise');
const envConfig = require('./envConfigurations/EnvConfigurations');
const connection = mysql.createConnection({
const pool = mysql.createPool({
host: envConfig.db.host,
port: envConfig.db.port,
user: envConfig.db.user,
password: envConfig.db.password,
database: envConfig.db.name
database: envConfig.db.name,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 40,
connectTimeout: 5000
});
connection.connect(err => {
if (err) {
console.error('Error al conectarse con la base de datos:', err);
return;
(async () => {
try {
const connection = await pool.getConnection();
console.log('Conectado con la base de datos');
connection.release();
} catch (err) {
console.error('Error al conectarse con la base de datos:', err.message);
process.exit(1);
}
console.log('Conectado con la base de datos');
});
})();
module.exports = connection;
module.exports = pool;
//IO
+2 -1
View File
@@ -22,4 +22,5 @@ const envConfig = {
}
};
module.exports = envConfig;
module.exports = envConfig;
//IO
+6
View File
@@ -37,6 +37,12 @@ app.get('/', (req, res) => {
res.send(textoLegal);
});
app.use((err, req, res, next) => {
console.error('Error general:', err.message);
console.error(err.stack);
res.status(500).json({ error: 'Error interno del servidor' });
});
app.listen(PORT, () => {
console.log(`Servidor al escucha en el puerto ${PORT}`);
});
+1
View File
@@ -7,3 +7,4 @@ module.exports = (req, res, next) => {
}
next();
}
//IO
+1
View File
@@ -16,3 +16,4 @@ function verifyToken(req, res, next) {
}
module.exports = verifyToken;
//IO
+52 -58
View File
@@ -1,82 +1,76 @@
const express = require('express');
const router = express.Router();
const connection = require('../db');
const pool = require('../db');
const impressionValidator = require('../validators/impressionValidator');
const handleValidation = require('../middleware/handleValidation');
const verifyToken = require('../middleware/verifyToken');
router.post('/',
verifyToken,
impressionValidator,
handleValidation,
(req, res) => {
impressionValidator,
async (req, res) => {
const { cost, numAccount, pages } = req.body;
const idUser = req.user.id_usuario;
connection.query(
'SELECT credito FROM alumno WHERE id_cuenta = ?',
[numAccount],
(err, results) => {
if (err) {
return res.status(500).json({ error: 'Error al consultar crédito del alumno'+ err });
}
let connection;
try {
// Obtener conexión del pool
connection = await pool.getConnection();
if (results.length === 0) {
return res.status(404).json({ error: 'Alumno no encontrado' });
}
// Consultar crédito actual
const [rows] = await connection.execute(
'SELECT credito FROM alumno WHERE id_cuenta = ?',
[numAccount]
);
const currentCredit = parseFloat(results[0].credito);
const requestedCost = parseFloat(cost);
if (rows.length === 0) {
return res.status(404).json({ error: 'Alumno no encontrado' });
}
if (isNaN(currentCredit) || isNaN(requestedCost)) {
return res.status(400).json({ error: 'Valores numéricos inválidos' });
}
const currentCredit = parseFloat(rows[0].credito);
const requestedCost = parseFloat(cost);
if (currentCredit < requestedCost) {
return res.status(400).json({ error: 'Crédito insuficiente' });
}
if (isNaN(currentCredit) || isNaN(requestedCost)) {
return res.status(400).json({ error: 'Valores numéricos inválidos' });
}
// Paso 3: Iniciar transacción
connection.beginTransaction((err) => {
if (err) {
return res.status(500).json({ error: 'Error al iniciar la transacción' });
}
if (currentCredit < requestedCost) {
return res.status(400).json({ error: 'Crédito insuficiente' });
}
const insertQuery = `
INSERT INTO detalle_servicio (monto, fecha_operacion, id_cuenta, id_servicio, id_usuario, numero_hojas)
VALUES (?, NOW(), ?, 1, ?, ?)
`;
connection.query(insertQuery, [requestedCost, numAccount, idUser, pages], (err, results) => {
if (err) {
return connection.rollback(() => {
res.status(500).json({ error: 'Error al insertar detalle_servicio' });
});
}
// Iniciar transacción
await connection.beginTransaction();
const updateQuery = `
UPDATE alumno SET credito = credito - ? WHERE id_cuenta = ?
`;
connection.query(updateQuery, [requestedCost, numAccount], (err, results) => {
if (err) {
return connection.rollback(() => {
res.status(500).json({ error: 'Error al actualizar crédito' });
});
}
// Insertar detalle de impresión
await connection.execute(
`INSERT INTO detalle_servicio
(monto, fecha_operacion, id_cuenta, id_servicio, id_usuario, numero_hojas)
VALUES (?, NOW(), ?, 1, ?, ?)`,
[requestedCost, numAccount, idUser, pages]
);
connection.commit((err) => {
if (err) {
return connection.rollback(() => {
res.status(500).json({ error: 'Error al confirmar transacción' });
});
}
// Actualizar crédito
await connection.execute(
'UPDATE alumno SET credito = credito - ? WHERE id_cuenta = ?',
[requestedCost, numAccount]
);
// Confirmar transacción
await connection.commit();
res.json({ message: 'Impresión registrada y crédito actualizado correctamente' });
} catch (err) {
if (connection) await connection.rollback();
console.error(err);
res.status(500).json({ error: 'Error en el servidor durante la impresión' });
} finally {
if (connection) connection.release();
}
res.json({ message: 'Impresión registrada y crédito actualizado correctamente' });
});
});
});
});
}
);
});
module.exports = router;
//IO
+27 -24
View File
@@ -1,42 +1,45 @@
const express = require('express');
const router = express.Router();
const connection = require('../db');
const pool = require('../db');
const loginValidator = require('../validators/loginValidator');
const handleValidation = require('../middleware/handleValidation');
const envConfig = require('../envConfigurations/EnvConfigurations');
const jwt = require('jsonwebtoken');
router.post('/',
loginValidator,
handleValidation,
(req, res) => {
loginValidator,
async (req, res) => {
const { user, password } = req.body;
connection.query(
'SELECT a.id_usuario , a.usuario , a.password , b.id_perfil , perfil FROM usuario a JOIN perfil b ON (a.id_perfil = b.id_perfil) WHERE a.usuario = ? AND a.password = ? AND a.activo = 1;',
[user, password],
(err, results) => {
if (err) {
return res.status(500).json({ error: 'Error al consultar ' + err });
}
if (results.length === 0) {
return res.status(404).json({ error: 'User o password incorrecta' });
}
const userData = results[0];
try {
const [results] = await pool.query(
'SELECT a.id_usuario , a.usuario , a.password , b.id_perfil , perfil FROM usuario a JOIN perfil b ON (a.id_perfil = b.id_perfil) WHERE a.usuario = ? AND a.password = ? AND a.activo = 1;',
[user, password]
)
const payload = {
id_usuario: userData.id_usuario,
usuario: userData.usuario,
perfil: userData.perfil,
id_perfil: userData.id_perfil,
};
if (results.length === 0) {
return res.status(404).json({ error: 'Usuario o contraseña incorrectos' });
}
const token = jwt.sign(payload, envConfig.jwtSecret, {
expiresIn: '8h',
});
const userData = results[0];
res.json({ token: token });
const payload = {
id_usuario: userData.id_usuario,
usuario: userData.usuario,
perfil: userData.perfil,
id_perfil: userData.id_perfil,
};
const token = jwt.sign(payload, envConfig.jwtSecret, {
expiresIn: '14h',
});
res.json({ token: token });
} catch (err) {
res.status(500).json({ error: 'Error al consultar: ' + err.message });
}
});
module.exports = router;
//IO
+32 -37
View File
@@ -1,54 +1,49 @@
const express = require('express');
const router = express.Router();
const connection = require('../db');
const pool = require('../db');
const receiptValidator = require('../validators/receiptValidator');
const handleValidation = require('../middleware/handleValidation');
const verifyToken = require('../middleware/verifyToken');
router.post('/',
verifyToken,
handleValidation,
receiptValidator,
handleValidation,
(req, res) => {
async (req, res) => {
const { fol, amount, date, numAccount } = req.body;
const idUser = req.user.id_usuario;
connection.query(
'SELECT * FROM recibo WHERE folio_recibo = ?;',
[fol],
(err, results) => {
if (err) {
return res.status(500).json({ error: 'Error al verificar recibo' + err });
}
if(amount > 1000){
return res.status(409).json({ error: 'El monto no puede superar $1000.00' });
}
if (results.length > 0) {
return res.status(409).json({ error: 'El recibo ya existe' });
}
connection.query(
'INSERT INTO recibo (folio_recibo, monto, fecha_recibo, id_cuenta, id_usuario) VALUES (?, ?, ?, ?, ?);',
[fol, amount, date, numAccount, idUser],
(err) => {
if (err) {
return res.status(500).json({ error: 'Error al guardar recibo' });
}
// Luego actualizamos el crédito
connection.query(
'UPDATE alumno SET credito = credito + ? WHERE id_cuenta = ?;',
[amount, numAccount],
(err) => {
if (err) {
return res.status(500).json({ error: 'Recibo guardado pero falló la actualización del crédito' });
}
res.json({ message: 'Recibo guardado correctamente y crédito actualizado' });
}
);
}
);
try {
const [existing] = await pool.execute(
'SELECT * FROM recibo WHERE folio_recibo = ?;',
[fol]
);
if (existing.length > 0) {
return res.status(409).json({ error: 'El recibo ya existe' });
}
);
await pool.execute(
'INSERT INTO recibo (folio_recibo, monto, fecha_recibo, id_cuenta, id_usuario) VALUES (?, ?, ?, ?, ?);',
[fol, amount, date, numAccount, idUser]
);
await pool.execute(
'UPDATE alumno SET credito = credito + ? WHERE id_cuenta = ?;',
[amount, numAccount]
);
res.json({ message: 'Recibo guardado correctamente y crédito actualizado' });
} catch (err) {
res.status(500).json({ error: 'Error en el servidor: '+ err });
}
});
module.exports = router;
//IO
+17 -15
View File
@@ -1,29 +1,31 @@
const express = require('express');
const router = express.Router();
const connection = require('../db');
const pool = require('../db');
const studentValidator = require('../validators/studentValidator');
const handleValidation = require('../middleware/handleValidation');
const verifyToken = require('../middleware/verifyToken');
router.post('/',
verifyToken,
studentValidator,
handleValidation,
(req, res) => {
studentValidator,
async (req, res) => {
const { numAccount } = req.body;
connection.query(
'SELECT a.id_cuenta, a.nombre , a.correo , a.credito, b.carrera FROM alumno a JOIN carrera b ON (a.id_carrera = b.id_carrera) WHERE a.id_cuenta = ?;',
[numAccount],
(err, results) => {
if (err) {
return res.status(500).json({ error: 'Error al consultar' + err });
}
if (results.length === 0) {
return res.status(404).json({ error: 'Alumno no encontrado' });
}
res.json(results);
try {
const [results] = await pool.query(
'SELECT a.id_cuenta, a.nombre , a.correo , a.credito, b.carrera FROM alumno a JOIN carrera b ON (a.id_carrera = b.id_carrera) WHERE a.id_cuenta = ?;',
[numAccount]
)
if (results.length === 0) {
return res.status(404).json({ error: 'Alumno no encontrado' });
}
);
res.json(results);
} catch (err) {
res.status(500).json({ error: 'Error al consultar: ' + err.message })
}
});
module.exports = router;
//IO
+1
View File
@@ -21,3 +21,4 @@ router.get('/', (req, res) => {
});
module.exports = router;
//IO
+1
View File
@@ -14,3 +14,4 @@ module.exports = [
.isInt().withMessage('Número de cuenta debe ser un número entero'),
];
//IO
+1
View File
@@ -9,3 +9,4 @@ module.exports = [
.notEmpty().withMessage('La contraseña es obligatoria')
.isString().withMessage('La contraseña debe ser una cadena')
];
//IO
+1
View File
@@ -17,3 +17,4 @@ module.exports = [
.notEmpty().withMessage('Número de cuenta obligatorio')
.isInt().withMessage('Número de cuenta debe ser un número entero'),
];
//IO
+1
View File
@@ -5,3 +5,4 @@ module.exports = [
.notEmpty().withMessage('El numero de cuenta es obligatorio')
.isInt().withMessage('Número de cuenta debe ser un número entero'),
];
//IO