Actualización módulo de usuarios e implementación de módulo catalogs

This commit is contained in:
2026-07-10 15:16:14 +00:00
parent 06b4ab7166
commit 9099a781a1
10 changed files with 593 additions and 55 deletions

View File

@ -1,18 +1,21 @@
import mongoose from "mongoose"; import mongoose from "mongoose";
export const connectMongo = async (): Promise <void> => { export const connectMongo = async () => {
try { try {
await mongoose.connect(process.env.MONGO_URI!); await mongoose.connect(
console.log("MongoDB conectado"); process.env.MONGO_URI!
);
console.log(
"MongoDB conectado"
);
} catch(error){ } catch(error){
console.error("Error MongoDB", error); console.error(error);
process.exit(1); process.exit(1);
} }
}; };

View File

@ -1,30 +1,30 @@
/*import sql from "mssql"; import sql from "mssql";
const config = {
const sqlConfig:sql.config = {
user: process.env.SQL_USER, user: process.env.SQL_USER,
password: process.env.SQL_PASSWORD,
server:process.env.SQL_SERVER!,
database:process.env.SQL_DATABASE,
options:{ password: process.env.SQL_PASSWORD,
trustServerCertificate:true,
encrypt:false server: process.env.SQL_SERVER!,
database: process.env.SQL_DATABASE!,
options: {
trustServerCertificate: true
} }
}; };
export async function getConnection(){
try {
const pool = await sql.connect(config);
return pool;
}catch(error) {
console.error("Error al conectar con SQLServer", error);
export const connectSqlServer = async() => { throw error;
try{
await sql.connect(sqlConfig);
console.log("SQL Server Conectado");
}catch(error){
console.error("Error SQL Server", error);
} }
}
};*/

View File

@ -0,0 +1,248 @@
import { Request, Response } from "express";
import { CatalogService } from "./catalog.service";
const service = new CatalogService();
export class CatalogController {
//Obtener todos los empleados
async getEmployees(
req: Request,
res: Response
) {
try {
const employees =
await service.getEmployees();
res.json(employees);
} catch (error) {
res.status(500).json({
message: "Error al obtener empleados",
error
});
}
}
//Obtener empleado por ID
async getEmployeeById(
req: Request,
res: Response
) {
try {
const employee =
await service.getEmployeeById(
Number(req.params.id)
);
if (!employee) {
return res.status(404).json({
message: "Empleado no encontrado"
});
}
res.json(employee);
} catch (error) {
res.status(500).json({
message: "Error al obtener empleado",
error
});
}
}
//Obtener todos los vehículos
async getVehicles(
req: Request,
res: Response
) {
try {
const vehicles =
await service.getVehicles();
res.json(vehicles);
} catch (error) {
res.status(500).json({
message: "Error al obtener vehículos",
error
});
}
}
//Obtener vehículo por ID
async getVehicleById(
req: Request,
res: Response
) {
try {
const vehicle =
await service.getVehicleById(
Number(req.params.id)
);
if (!vehicle) {
return res.status(404).json({
message: "Vehículo no encontrado"
});
}
res.json(vehicle);
} catch (error) {
res.status(500).json({
message: "Error al obtener vehículo",
error
});
}
}
//Obtener todos los departamentos
async getDepartments(
req: Request,
res: Response
) {
try {
const departments =
await service.getDepartments();
res.json(departments);
} catch (error) {
res.status(500).json({
message: "Error al obtener departamentos",
error
});
}
}
//Obtener departamento por ID
async getDepartmentById(
req: Request,
res: Response
) {
try {
const department =
await service.getDepartmentById(
Number(req.params.id)
);
if (!department) {
return res.status(404).json({
message: "Departamento no encontrado"
});
}
res.json(department);
} catch (error) {
res.status(500).json({
message: "Error al obtener departamento",
error
});
}
}
//Obtener todas las rutas
async getRoutes(
req: Request,
res: Response
) {
try {
const routes =
await service.getRoutes();
res.json(routes);
} catch (error) {
res.status(500).json({
message: "Error al obtener rutas",
error
});
}
}
//Obtener ruta por ID
async getRouteById(
req: Request,
res: Response
) {
try {
const route =
await service.getRouteById(
Number(req.params.id)
);
if (!route) {
return res.status(404).json({
message: "Ruta no encontrada"
});
}
res.json(route);
} catch (error) {
res.status(500).json({
message: "Error al obtener ruta",
error
});
}
}
}

View File

@ -0,0 +1,41 @@
import { Router } from "express";
import { CatalogController } from "./catalog.controller";
import { authMiddleware } from "../auth/auth.middleware";
import { permissionMiddleware } from "../auth/permission.middleware";
const catalogRouter = Router();
const controller = new CatalogController();
//EMPLEADOS
// Obtener todos los empleados
catalogRouter.get("/employees", authMiddleware, permissionMiddleware("catalogs", "read"), controller.getEmployees);
// Obtener empleado por ID
catalogRouter.get("/employees/:id", authMiddleware, permissionMiddleware("catalogs", "read"), controller.getEmployeeById);
//VEHÍCULOS
// Obtener todos los vehículos
catalogRouter.get("/vehicles", authMiddleware, permissionMiddleware("catalogs", "read"), controller.getVehicles);
// Obtener vehículo por ID
catalogRouter.get("/vehicles/:id", authMiddleware, permissionMiddleware("catalogs", "read"), controller.getVehicleById);
//DEPARTAMENTOS
// Obtener todos los departamentos
catalogRouter.get("/departments", authMiddleware, permissionMiddleware("catalogs", "read"), controller.getDepartments);
// Obtener departamento por ID
catalogRouter.get("/departments/:id", authMiddleware, permissionMiddleware("catalogs", "read"), controller.getDepartmentById);
// RUTAS
// Obtener todas las rutas
catalogRouter.get("/routes", authMiddleware, permissionMiddleware("catalogs", "read"), controller.getRoutes);
// Obtener ruta por ID
catalogRouter.get("/routes/:id", authMiddleware, permissionMiddleware("catalogs", "read"), controller.getRouteById);
export default catalogRouter;

View File

@ -0,0 +1,173 @@
import { getConnection } from "../../config/sqlserver";
export class CatalogService {
//Obtener todos los empleados
async getEmployees() {
const pool = await getConnection();
const result = await pool
.request()
.query(`
SELECT *
FROM vw_Empleados
ORDER BY id_empleado
`);
return result.recordset;
}
//Obtener un empleado por código
async getEmployeeById(
employeeId: number
) {
const pool = await getConnection();
const result = await pool
.request()
.input(
"id_empleado",
employeeId
)
.query(`
SELECT *
FROM vw_Empleados
WHERE id_empleado = @id_empleado
`);
return result.recordset[0];
}
//Obtener todos los vehículos
async getVehicles() {
const pool = await getConnection();
const result = await pool
.request()
.query(`
SELECT *
FROM vw_Vehiculos
ORDER BY id_vehiculo
`);
return result.recordset;
}
//Obtener vehículo por código
async getVehicleById(
vehicleId: number
) {
const pool = await getConnection();
const result = await pool
.request()
.input(
"id_vehiculo",
vehicleId
)
.query(`
SELECT *
FROM vw_Vehiculos
WHERE id_vehiculo = @id_vehiculo
`);
return result.recordset[0];
}
//Obtener departamentos
async getDepartments() {
const pool = await getConnection();
const result = await pool
.request()
.query(`
SELECT *
FROM vw_Departamentos
ORDER BY id_departamento
`);
return result.recordset;
}
//Obtener departamento por código
async getDepartmentById(
departmentId: number
) {
const pool = await getConnection();
const result = await pool
.request()
.input(
"id_departamento",
departmentId
)
.query(`
SELECT *
FROM vw_Departamentos
WHERE id_departamento = @id_departamento
`);
return result.recordset[0];
}
//Obtener rutas
async getRoutes() {
const pool = await getConnection();
const result = await pool
.request()
.query(`
SELECT *
FROM vw_Rutas
ORDER BY id_ruta
`);
return result.recordset;
}
//Obtener ruta por código
async getRouteById(
routeId: number
) {
const pool = await getConnection();
const result = await pool
.request()
.input(
"id_ruta",
routeId
)
.query(`
SELECT *
FROM vw_Rutas
WHERE id_ruta = @id_ruta
`);
return result.recordset[0];
}
}

View File

@ -54,15 +54,14 @@ export class UserController {
res:Response res:Response
) { ) {
try { try {
const user = const user = await userService.create(
await userService.create(
req.body req.body
); );
res.status(201).json(user); res.status(201).json(user);
}catch(error){ }catch (error:any) {
res.status(500).json({ res.status(500).json({
message:"Error al crear usuario", message: error.message,
error error
}); });
@ -120,5 +119,4 @@ export class UserController {
}); });
} }
} }
} }

View File

@ -13,6 +13,7 @@ const userSchema = new mongoose.Schema({
type:String, type:String,
required:true, required:true,
unique:true, unique:true,
trim:true
}, },
passwordHash:{ passwordHash:{

View File

@ -1,20 +1,22 @@
import { Router } from "express"; import { Router } from "express";
import { UserController } from "./user.controller"; import { UserController } from "./user.controller";
import { authMiddleware } from "../auth/auth.middleware"; import { authMiddleware } from "../auth/auth.middleware";
import { permissionMiddleware } from "../auth/permission.middleware";
const userRouter = Router(); const userRouter = Router();
const controller = new UserController(); const controller = new UserController();
userRouter.get("/", authMiddleware, controller.getAll); userRouter.get("/", authMiddleware, permissionMiddleware("users", "read"), controller.getAll);
userRouter.get("/:id", authMiddleware, controller.getById); userRouter.get("/:id", authMiddleware, permissionMiddleware("users", "read"), controller.getById);
userRouter.post("/", controller.create); userRouter.post("/", authMiddleware, permissionMiddleware("users", "create"), controller.create);
userRouter.put("/:id", authMiddleware, controller.update); userRouter.put("/:id", authMiddleware, permissionMiddleware("users", "update"), controller.update);
userRouter.delete("/:id", authMiddleware, controller.delete); userRouter.delete("/:id", authMiddleware, permissionMiddleware("users", "delete"), controller.delete);
export default userRouter; export default userRouter;

View File

@ -1,6 +1,9 @@
import bcrypt from "bcrypt"; import bcrypt from "bcrypt";
import userModel from "./user.model"; import userModel from "./user.model";
import { IUser } from "./user.interface"; import { IUser } from "./user.interface";
import { CatalogService } from "../catalogs/catalog.service";
const catalogService = new CatalogService();
export class UserService { export class UserService {
@ -22,6 +25,33 @@ export class UserService {
async create( async create(
data:IUser data:IUser
) { ) {
//Validar que el empleado exista
const employee = await catalogService.getEmployeeById(
data.employeeId
);
if(!employee){
throw new Error( "El empleado no existe.")
}
//Validar que el empelado no tenga usuario
const employeeExist = await userModel.findOne({
employeeId:data.employeeId
});
if(employeeExist){
throw new Error ("El empleado ya tiene usuario registrado");
}
//Validar nombre de usuario
const userNameExist = await userModel.findOne({
userName:data.userName
});
if(userNameExist){
throw new Error("El nombre del usuario ya existe");
}
const passwordHash = await bcrypt.hash( const passwordHash = await bcrypt.hash(
data.passwordHash, data.passwordHash,
10 10
@ -36,6 +66,53 @@ export class UserService {
id:string, id:string,
data:Partial<IUser> data:Partial<IUser>
) { ) {
const user = await userModel.findById(id);
if (!user) {
return null;
}
// Validar empleado
if (data.employeeId !== undefined) {
const employee = await catalogService.getEmployeeById(
data.employeeId
);
if (!employee) {
throw new Error("El empleado no existe.");
}
const employeeExists =
await userModel.findOne({
employeeId: data.employeeId,
_id: { $ne: id }
});
if (employeeExists) {
throw new Error(
"El empleado ya tiene un usuario registrado."
);
}
}
// Validar nombre de usuario
if (data.userName !== undefined) {
const userNameExists =
await userModel.findOne({
userName: data.userName,
_id: { $ne: id }
});
if (userNameExists) {
throw new Error("El nombre de usuario ya existe.");
}
}
if(data.passwordHash){ if(data.passwordHash){
data.passwordHash = await bcrypt.hash( data.passwordHash = await bcrypt.hash(
data.passwordHash, data.passwordHash,

View File

@ -2,30 +2,25 @@ import dotenv from "dotenv";
dotenv.config(); dotenv.config();
import { connectMongo } from "./config/mongodb";
//import { connectSqlServer } from "./config/sqlserver";
import app from "./app"; import app from "./app";
const PORT = process.env.PORT || 5000; import { connectMongo } from "./config/mongodb";
const startServer = async() => {
try { const startServer =
async () => {
await connectMongo(); await connectMongo();
//await connectSqlServer();
app.listen(
process.env.PORT,
() => {
app.listen(PORT, () => { console.log(
`Servidor iniciado en puerto ${process.env.PORT}`
console.log(`Servidor ejecutandose en puerto ${PORT}`); );
});
}catch(error){
console.error("Error al iniciar el servidor", error);
} }
);
}; };
startServer(); startServer();