From 3ab69a831aa50e05de71ebaefb5124dadd480648 Mon Sep 17 00:00:00 2001 From: karol Date: Thu, 9 Jul 2026 14:54:13 +0000 Subject: [PATCH] =?UTF-8?q?Implementaci=C3=B3n=20del=20m=C3=B3dulo=20de=20?= =?UTF-8?q?permisos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../permissions/permission.controller.ts | 165 ++++++++++++++++++ .../permissions/permission.interface.ts | 18 ++ .../modules/permissions/permission.model.ts | 44 +++++ .../modules/permissions/permission.routes.ts | 21 +++ .../modules/permissions/permission.service.ts | 129 ++++++++++++++ 5 files changed, 377 insertions(+) create mode 100644 backend/src/modules/permissions/permission.controller.ts create mode 100644 backend/src/modules/permissions/permission.interface.ts create mode 100644 backend/src/modules/permissions/permission.model.ts create mode 100644 backend/src/modules/permissions/permission.routes.ts create mode 100644 backend/src/modules/permissions/permission.service.ts diff --git a/backend/src/modules/permissions/permission.controller.ts b/backend/src/modules/permissions/permission.controller.ts new file mode 100644 index 0000000..51201ed --- /dev/null +++ b/backend/src/modules/permissions/permission.controller.ts @@ -0,0 +1,165 @@ +import { Request, Response } from "express"; +import { PermissionService } from "./permission.service"; + +const service = new PermissionService(); + +export class PermissionController{ + + async getAll( + req:Request, + res:Response + ){ + + try{ + const permissions = await service.getAll(); + res.json(permissions); + + } catch (error){ + res.status(500).json({ + message:"Error al obtener permisos", + error + }); + } + } + + async getById( + req:Request, + res:Response + ){ + try{ + + const permission = await service.getById( + req.params.id as string + ); + + if(!permission) { + return res.status(404).json({ + message: + "Permiso no encontrado" + }); + } + + res.json(permission) + } catch(error){ + res.status(500).json({ + message:"Error al obtener permiso" + }); + } + } + + async create( + req:Request, + res:Response + ){ + try{ + const permission = await service.create( + req.body + ); + + res.status(201).json( + permission + ); + + }catch(error){ + res.status(500).json({ + message:"Error al crear permiso", + error + }); + } + } + + async update( + req:Request, + res:Response + ){ + try{ + const permission = await service.update( + req.params.id as string, + req.body + ) + + if (!permission) { + return res.status(404).json({ + message: + "Permiso no encontrado" + }); + } + + }catch(error){ + res.status(500).json({ + message:"Error al actualizar permiso", + error + }); + } + } + + async getByModule( + req:Request, + res:Response + ){ + try{ + + const permission = await service.getByModule( + req.params.module as string + ); + + res.json(permission) + + }catch(error){ + res.status(500).json({ + message:"Error al obtener los permisos del módulo " + }); + + } + } + + async getByModuleandAction( + req:Request, + res:Response + ){ + try{ + + const permission = await service.getByModuleandAction( + req.params.module as string, + req.params.action as string + ); + + res.json(permission) + + }catch(error){ + res.status(500).json({ + message:"Error al obtener el permiso " + }); + + } + } + + async delete( + req:Request, + res:Response + ){ + try{ + const permission = await service.delete( + req.params.id as string + ) + + if(!permission){ + return res.status(404).json({ + message: + "Permiso no encontrado" + }); + } + res.json({ + message:"Permiso eliminado correctamente" + }); + + }catch(error){ + + res.status(500).json({ + message:"Error al eliminar permiso" + }); + } + } + + +} \ No newline at end of file diff --git a/backend/src/modules/permissions/permission.interface.ts b/backend/src/modules/permissions/permission.interface.ts new file mode 100644 index 0000000..aea5b24 --- /dev/null +++ b/backend/src/modules/permissions/permission.interface.ts @@ -0,0 +1,18 @@ +import { Types } from "mongoose"; + +export interface IPermission { + + _id:Types.ObjectId, + + name:string, + + module:string, + + action:string, + + description?:string, + + active:boolean, + + createdBy:Types.ObjectId +} \ No newline at end of file diff --git a/backend/src/modules/permissions/permission.model.ts b/backend/src/modules/permissions/permission.model.ts new file mode 100644 index 0000000..046de20 --- /dev/null +++ b/backend/src/modules/permissions/permission.model.ts @@ -0,0 +1,44 @@ +import mongoose from "mongoose"; +import { IPermission } from "./permission.interface"; + +const permissionSchema = new mongoose.Schema({ + + name:{ + type:String, + required:true, + unique:true, + trim:true + }, + + module:{ + type:String, + required:true, + }, + + action:{ + type:String, + required:true + }, + + description:{ + type:String, + }, + + active:{ + type:Boolean, + default:true + }, + + createdBy:{ + type:mongoose.Schema.Types.ObjectId, + ref:"User", + required:true + } +}, + { + timestamps:true, + versionKey:false + } +); + +export default mongoose.model("Permission", permissionSchema); \ No newline at end of file diff --git a/backend/src/modules/permissions/permission.routes.ts b/backend/src/modules/permissions/permission.routes.ts new file mode 100644 index 0000000..a93a6ac --- /dev/null +++ b/backend/src/modules/permissions/permission.routes.ts @@ -0,0 +1,21 @@ +import { Router } from "express"; +import { PermissionController } from "./permission.controller"; +import { authMiddleware } from "../auth/auth.middleware"; + +const permissionRouter = Router(); + +const controller = new PermissionController(); + +permissionRouter.get("/", authMiddleware, controller.getAll); + +permissionRouter.get("/module/:module", authMiddleware, controller.getByModule); + +permissionRouter.get("/module/:module/action/:action", authMiddleware, controller.getByModule); + +permissionRouter.get("/:id", authMiddleware, controller.getById); + +permissionRouter.post("/", authMiddleware, controller.create); + +permissionRouter.put("/:id", authMiddleware, controller.update); + +permissionRouter.delete("/:id", authMiddleware, controller.delete); \ No newline at end of file diff --git a/backend/src/modules/permissions/permission.service.ts b/backend/src/modules/permissions/permission.service.ts new file mode 100644 index 0000000..9ecd99c --- /dev/null +++ b/backend/src/modules/permissions/permission.service.ts @@ -0,0 +1,129 @@ +import permissionModel from "./permission.model"; +import { IPermission } from './permission.interface'; + + +export class PermissionService{ + + async getAll(){ + + return await permissionModel + .find() + .populate( + "createdBy", + "userName" + ).sort({ + + module:1, + action:1 + }); + } + + async getById( + id:string + ){ + + return await permissionModel + .findById(id) + .populate( + "createdBy", + "userName" + ).sort({ + module:1, + action:1 + }); + } + + async create( + data:IPermission + ){ + const exists = await permissionModel.findOne({ + module:data.module, + + action:data.action + }); + + if(exists){ + throw new Error ("Ya existe un permiso para este módulo y esta acción"); + } + + return await permissionModel.create( + data + ); + } + + async update( + id:string, + data:Partial + ){ + if( + data.module && + data.action + ){ + const exists = await permissionModel.findOne({ + module:data.module, + + action:data.action, + + _id:{ + $ne:id + } + }); + + if(exists){ + throw new Error ("Ya existe un permiso para este módulo y esta acción"); + } + } + + return await permissionModel.findByIdAndUpdate( + id, + data, + { + new:true + } + ); + } + //Obtener por módulo + + async getByModule( + module:string, + + ){ + return await permissionModel + .findOne({ + module, + active:true + }) + .populate( + "createdBy", + "userName") + .sort({ + action:1 + }) + + } + + //Obtener por módulo y acción + + async getByModuleandAction( + module:string, + action:string + ){ + return await permissionModel.findOne({ + module, + action, + active:true + }).populate( + "createdBy", + "userName") + } + + //Eliminar permiso + + async delete( + id:string + ){ + return await permissionModel.findByIdAndDelete( + id + ); + } +} \ No newline at end of file