]> PHS Git Server - phs-api.git/commitdiff
Adding role models, routes, and controllers.
authorcharleswrayjr <charleswrayjr@gmail.com>
Fri, 12 Sep 2025 04:16:23 +0000 (23:16 -0500)
committercharleswrayjr <charleswrayjr@gmail.com>
Fri, 12 Sep 2025 04:16:23 +0000 (23:16 -0500)
src/controllers/role.controller.js [new file with mode: 0644]
src/controllers/user_roles.controller.js [new file with mode: 0644]
src/models/index.js
src/models/role.model.js [new file with mode: 0644]
src/models/user_roles.model.js [new file with mode: 0644]
src/routes/index.js
src/routes/role.routes.js [new file with mode: 0644]
src/routes/user_roles.routes.js [new file with mode: 0644]

diff --git a/src/controllers/role.controller.js b/src/controllers/role.controller.js
new file mode 100644 (file)
index 0000000..3050ac1
--- /dev/null
@@ -0,0 +1,128 @@
+/**
+ * @file Role controller for handling role-related API requests
+ */
+
+const db = require( '../models' );
+const createError = require( 'http-errors' );
+
+/**
+ * Role controller
+ * @type {Object}
+ */
+module.exports = {
+  /**
+   * Create a new role
+   * @param {Object} req - Express request object
+   * @param {Object} res - Express response object
+   * @param {Function} next - Express next middleware function
+   * @returns {Promise<void>}
+   */
+  async create( req, res, next ) {
+    try {
+      const role_data = req.body;
+      const role = await db.role.create( role_data );
+      res.json( role );
+    } catch (error) {
+      logger.error( `Create role error: ${ error.message }` );
+      next( createError( error.status || 409, error.message ) );
+    }
+  },
+
+  /**
+   * Find role by name
+   * @param {Object} req - Express request object
+   * @param {Object} res - Express response object
+   * @param {Function} next - Express next middleware function
+   * @returns {Promise<void>}
+   */
+  async find_by_name( req, res, next ) {
+    try {
+      const { name } = req.params;
+      const role = await db.role.find_by_name( name );
+      if (!role) return next( createError( 404, 'Role not found' ) );
+      res.json( role );
+    } catch (error) {
+      logger.error( `Find role by name error: ${ error.message }` );
+      next( createError( error.status || 500, error.message ) );
+    }
+  },
+
+  /**
+   * Find one role by ID
+   * @param {Object} req - Express request object
+   * @param {Object} res - Express response object
+   * @param {Function} next - Express next middleware function
+   * @returns {Promise<void>}
+   */
+  async find_one( req, res, next ) {
+    try {
+      const { id } = req.params;
+      const role = await db.role.find_one( { id:parseInt( id ) } );
+      if (!role) return next( createError( 404, 'Role not found' ) );
+      res.json( role );
+    } catch (error) {
+      logger.error( `Find role error: ${ error.message }` );
+      next( createError( error.status || 500, error.message ) );
+    }
+  },
+
+  /**
+   * Find many roles
+   * @param {Object} req - Express request object
+   * @param {Object} res - Express response object
+   * @param {Function} next - Express next middleware function
+   * @returns {Promise<void>}
+   */
+  async find_many( req, res, next ) {
+    try {
+      const { limit = '100', offset = '0', ...where } = req.query;
+      const roles = await db.role.find_many( where, [], null, parseInt( limit ), parseInt( offset ) );
+      res.json( roles );
+    } catch (error) {
+      logger.error( `Find many roles error: ${ error.message }` );
+      next( createError( error.status || 500, error.message ) );
+    }
+  },
+
+  /**
+   * Update a role
+   * @param {Object} req - Express request object
+   * @param {Object} res - Express response object
+   * @param {Function} next - Express next middleware function
+   * @returns {Promise<void>}
+   */
+  async update( req, res, next ) {
+    try {
+      const { id } = req.params;
+      const role_data = req.body;
+      const role = await db.role.instance().find_one( { id:parseInt( id ) } );
+      if (!role) return next( createError( 404, 'Role not found' ) );
+      const updated_role = await role.update( role_data );
+      res.json( updated_role );
+    } catch (error) {
+      logger.error( `Update role error: ${ error.message }` );
+      next( createError( error.status || 400, error.message ) );
+    }
+  },
+
+  /**
+   * Soft delete a role
+   * @param {Object} req - Express request object
+   * @param {Object} res - Express response object
+   * @param {Function} next - Express next middleware function
+   * @returns {Promise<void>}
+   */
+  async soft_delete( req, res, next ) {
+    try {
+      const { id } = req.params;
+      const { deleted_by_id } = req.body;
+      const role = await db.role.instance().find_one( { id:parseInt( id ) } );
+      if (!role) return next( createError( 404, 'Role not found' ) );
+      const deleted_role = await role.soft_delete( deleted_by_id );
+      res.json( deleted_role );
+    } catch (error) {
+      logger.error( `Soft delete role error: ${ error.message }` );
+      next( createError( error.status || 400, error.message ) );
+    }
+  }
+};
\ No newline at end of file
diff --git a/src/controllers/user_roles.controller.js b/src/controllers/user_roles.controller.js
new file mode 100644 (file)
index 0000000..be3e2cb
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * @file User roles controller for handling user role-related API requests
+ */
+
+const db = require( '../models' );
+const createError = require( 'http-errors' );
+
+/**
+ * User roles controller
+ * @type {Object}
+ */
+module.exports = {
+  /**
+   * Add a user-role relation
+   * @param {Object} req - Express request object
+   * @param {Object} res - Express response object
+   * @param {Function} next - Express next middleware function
+   * @returns {Promise<void>}
+   */
+  async add_relation( req, res, next ) {
+    try {
+      const { user_id, role_id } = req.body;
+      const relation = await db.user_roles.add_relation( user_id, role_id );
+      res.json( relation );
+    } catch (error) {
+      logger.error( `Add user-role relation error: ${ error.message }` );
+      next( createError( error.status || 409, error.message ) );
+    }
+  },
+
+  /**
+   * Remove a user-role relation
+   * @param {Object} req - Express request object
+   * @param {Object} res - Express response object
+   * @param {Function} next - Express next middleware function
+   * @returns {Promise<void>}
+   */
+  async remove_relation( req, res, next ) {
+    try {
+      const { role_id, user_id } = req.body;
+      const relation = await db.user_roles.remove_relation( role_id, user_id );
+      if (!relation) return next( createError( 404, 'Relation not found' ) );
+      res.json( relation );
+    } catch (error) {
+      logger.error( `Remove user-role relation error: ${ error.message }` );
+      next( createError( error.status || 400, error.message ) );
+    }
+  },
+
+  /**
+   * Find user-role relation by IDs
+   * @param {Object} req - Express request object
+   * @param {Object} res - Express response object
+   * @param {Function} next - Express next middleware function
+   * @returns {Promise<void>}
+   */
+  async find_by_ids( req, res, next ) {
+    try {
+      const { user_id, role_id } = req.params;
+      const relation = await db.user_roles.find_by_ids( parseInt( user_id ), parseInt( role_id ) );
+      if (!relation) return next( createError( 404, 'Relation not found' ) );
+      res.json( relation );
+    } catch (error) {
+      logger.error( `Find user-role by IDs error: ${ error.message }` );
+      next( createError( error.status || 500, error.message ) );
+    }
+  },
+
+  /**
+   * Find user-role relations by user ID
+   * @param {Object} req - Express request object
+   * @param {Object} res - Express response object
+   * @param {Function} next - Express next middleware function
+   * @returns {Promise<void>}
+   */
+  async find_by_user_id( req, res, next ) {
+    try {
+      const { user_id } = req.params;
+      const { limit = '100', offset = '0' } = req.query;
+      const relations = await db.user_roles.find_by_user_id( parseInt( user_id ), [], null, parseInt( limit ), parseInt( offset ) );
+      res.json( relations );
+    } catch (error) {
+      logger.error( `Find user-roles by user ID error: ${ error.message }` );
+      next( createError( error.status || 500, error.message ) );
+    }
+  }
+};
\ No newline at end of file
index 39cd411ccec0aaddda3b9cc25a6e38261b5ac410..d6d6f72f1448e0d33cab15e542d13cf50f9119c1 100644 (file)
@@ -49,6 +49,16 @@ const get_user_addresses_model = () => get_model( 'user_addresses' );
  */
 const get_authentication_model = () => get_model( 'authentication' );
 
+/**
+ * @returns {Function} Role model class
+ */
+const get_role_model = () => get_model( 'role' );
+
+/**
+ * @returns {Function} User roles model class
+ */
+const get_user_roles_model = () => get_model( 'user_roles' );
+
 /**
  * Unified database interface
  * @type {Object}
@@ -620,6 +630,143 @@ const db = {
      * @returns {Authentication} Authentication instance
      */
     instance:() => new (get_authentication_model())()
+  },
+  role:{
+    /**
+     * Create a new role
+     * @param {Object} role_data - Role data
+     * @returns {Promise<Role>} Created role instance
+     * @throws {ValidationError} If required fields are missing
+     * @throws {FailedToCreateError} If creation fails
+     */
+    async create( role_data ) {
+      try {
+        return await get_role_model().create( role_data );
+      } catch (error) {
+        logger.error( `Failed to create role: ${ error.message }` );
+        throw error;
+      }
+    },
+    /**
+     * Find role by name
+     * @param {string} name - Role name to search for
+     * @param {string[]} [excludes] - Fields to exclude
+     * @returns {Promise<Role|null>} Role instance or null
+     */
+    async find_by_name( name, excludes ) {
+      try {
+        return await get_role_model().find_by_name( name, excludes );
+      } catch (error) {
+        logger.error( `Failed to find role by name: ${ error.message }` );
+        throw error;
+      }
+    },
+    /**
+     * Find one role
+     * @param {Object} where - Conditions
+     * @param {string[]} [excludes] - Fields to exclude
+     * @returns {Promise<Role|null>} Role instance or null
+     */
+    async find_one( where, excludes ) {
+      try {
+        return await new (get_role_model())().find_one( where, excludes );
+      } catch (error) {
+        logger.error( `Failed to find one role: ${ error.message }` );
+        throw error;
+      }
+    },
+    /**
+     * Find many roles
+     * @param {Object} [where] - Conditions
+     * @param {string[]} [excludes] - Fields to exclude
+     * @param {{name: string, direction?: 'asc'|'desc'}||null} [order_by] - Order by configuration
+     * @param {number} [limit] - Maximum number of records
+     * @param {number} [offset] - Number of records to skip
+     * @returns {Promise<Role[]>} Array of roles
+     */
+    async find_many( where, excludes, order_by, limit, offset ) {
+      try {
+        return await new (get_role_model())().find_many( where, excludes, order_by, limit, offset );
+      } catch (error) {
+        logger.error( `Failed to find many roles: ${ error.message }` );
+        throw error;
+      }
+    },
+    /**
+     * Create a new Role instance
+     * @returns {Role} Role instance
+     */
+    instance:() => new (get_role_model())()
+  },
+  user_roles:{
+    /**
+     * Add a user-role relation
+     * @param {number|string} user_id - User ID
+     * @param {number|string} role_id - Role ID
+     * @returns {Promise<UserRole>} Created relation instance
+     * @throws {ValidationError} If IDs are invalid
+     * @throws {FailedToCreateError} If creation fails
+     */
+    async add_relation( user_id, role_id ) {
+      try {
+        return await get_user_roles_model().add_relation( user_id, role_id );
+      } catch (error) {
+        logger.error( `Failed to add user-role relation: ${ error.message }` );
+        throw error;
+      }
+    },
+    /**
+     * Remove a user-role relation
+     * @param {number|string} role_id - Role ID
+     * @param {number|string|undefined} [user_id] - User ID
+     * @returns {Promise<UserRole|null>} Deleted relation instance or null
+     * @throws {ValidationError} If IDs are invalid
+     */
+    async remove_relation( role_id, user_id ) {
+      try {
+        return await get_user_roles_model().remove_relation( role_id, user_id );
+      } catch (error) {
+        logger.error( `Failed to remove user-role relation: ${ error.message }` );
+        throw error;
+      }
+    },
+    /**
+     * Find user-role relation by IDs
+     * @param {number|string} user_id - User ID
+     * @param {number|string} role_id - Role ID
+     * @param {string[]} [excludes] - Fields to exclude
+     * @returns {Promise<UserRole|null>} Relation instance or null
+     */
+    async find_by_ids( user_id, role_id, excludes ) {
+      try {
+        return await get_user_roles_model().find_by_ids( user_id, role_id, excludes );
+      } catch (error) {
+        logger.error( `Failed to find user-role by IDs: ${ error.message }` );
+        throw error;
+      }
+    },
+    /**
+     * Find user-role relations by user ID
+     * @param {number|string} user_id - User ID
+     * @param {string[]} [excludes] - Fields to exclude
+     * @param {{name: string, direction?: 'asc'|'desc'}||null} [order_by] - Order by configuration
+     * @param {number} [limit] - Maximum number of records
+     * @param {number} [offset] - Number of records to skip
+     * @returns {Promise<UserRole[]>} Array of relations
+     */
+    async find_by_user_id( user_id, excludes, order_by, limit, offset ) {
+      try {
+        return await get_user_roles_model().find_by_user_id( user_id, excludes, order_by, limit, offset );
+      } catch (error) {
+        logger.error( `Failed to find user-roles by user ID: ${ error.message }` );
+        throw error;
+      }
+    },
+    /**
+     * Create a new UserRole instance
+     * @returns {UserRole} UserRole instance
+     */
+    instance:() => new (get_user_roles_model())()
   }
 };
 
diff --git a/src/models/role.model.js b/src/models/role.model.js
new file mode 100644 (file)
index 0000000..94a4753
--- /dev/null
@@ -0,0 +1,109 @@
+/**
+ * @file Role model for phase.roles table
+ */
+
+const { Model, NotFoundError, ValidationError, FailedToCreateError } = require( './model' );
+
+/**
+ * @typedef {Object} Role
+ * @property {number} id - Role ID (primary key)
+ * @property {string} name - Role name
+ * @property {number} created_by_id - ID of user who created this role
+ * @property {Date} created_at - Creation timestamp
+ * @property {boolean} is_deleted - Soft delete flag
+ * @property {number|null} deleted_by_id - ID of user who deleted this role
+ * @property {Date|null} deleted_at - Deletion timestamp
+ */
+
+/**
+ * Role model class
+ * @extends Model
+ */
+class Role extends Model {
+  /**
+   * Create a Role instance
+   * @param {Partial<Role>} [props] - Role properties
+   */
+  constructor( props ) {
+    super( props );
+    this.table = 'phase.roles';
+    this.prepend = 'r';
+    this.default_columns = [
+      'id', 'name', 'created_by_id', 'created_at',
+      'is_deleted', 'deleted_by_id', 'deleted_at'
+    ];
+    this.update_exclude_columns = ['id', 'created_at', 'is_deleted', 'deleted_at', 'deleted_by_id'];
+    this.base_query = `
+        SELECT r.id,
+               r.name,
+               r.created_by_id,
+               r.created_at,
+               r.is_deleted,
+               r.deleted_by_id,
+               r.deleted_at
+        FROM phase.roles r
+        WHERE r.is_deleted = false
+    `;
+    this.base_list_query = `
+        SELECT r.id, r.name, r.created_by_id, r.created_at
+        FROM phase.roles r
+        WHERE r.is_deleted = false
+    `;
+    this.default_order_by = 'ORDER BY r.name ASC';
+    this.instance = _props => new Role( _props );
+  }
+
+  /**
+   * Create a new role
+   * @param {Omit<Role, 'id'|'created_at'|'is_deleted'|'deleted_at'|'deleted_by_id'>} role_data - Role data
+   * @returns {Promise<Role>} Created role instance
+   * @throws {ValidationError} If required fields are missing
+   * @throws {FailedToCreateError} If creation fails
+   */
+  static async create( role_data ) {
+    const { name, created_by_id } = role_data;
+    if (!name || !created_by_id) {
+      throw new ValidationError( 'Missing required fields: name, created_by_id' );
+    }
+    const query_str = `
+        INSERT INTO phase.roles (name, created_by_id)
+        VALUES ($1, $2)
+        RETURNING *;
+    `;
+    const values = [name, created_by_id];
+    const result = await phsdb.query( query_str, values, { plain:true } );
+    if (!result) throw new FailedToCreateError( 'Failed to create role' );
+    return new Role( result );
+  }
+
+  /**
+   * Find role by name
+   * @param {string} name - Role name to search for
+   * @param {string[]} [excludes] - Fields to exclude from result
+   * @returns {Promise<Role|null>} Role instance or null
+   */
+  static async find_by_name( name, excludes = [] ) {
+    return await new Role().find_one( { name }, excludes );
+  }
+
+  /**
+   * Soft delete role
+   * @param {number|string} deleted_by_id - ID of user performing deletion
+   * @returns {Promise<Role>} Updated role instance
+   * @throws {ValidationError} If deleted_by_id is invalid
+   * @throws {NotFoundError} If record not found
+   */
+  async soft_delete( deleted_by_id ) {
+    const deleted_by_id_int = parseInt( deleted_by_id, 10 );
+    if (isNaN( deleted_by_id_int )) {
+      throw new ValidationError( 'deleted_by_id must be a valid integer' );
+    }
+    return await this.update( {
+      is_deleted:true,
+      deleted_at:new Date().toISOString(),
+      deleted_by_id:deleted_by_id_int
+    } );
+  }
+}
+
+module.exports = Role;
\ No newline at end of file
diff --git a/src/models/user_roles.model.js b/src/models/user_roles.model.js
new file mode 100644 (file)
index 0000000..07080bf
--- /dev/null
@@ -0,0 +1,121 @@
+/**
+ * @file User roles model for phase.user_roles table
+ */
+
+const { Model, ValidationError, FailedToCreateError } = require( './model' );
+
+/**
+ * @typedef {Object} UserRole
+ * @property {number} user_id - User ID (foreign key)
+ * @property {number} role_id - Role ID (foreign key)
+ */
+
+/**
+ * User role model class
+ * @extends Model
+ */
+class UserRole extends Model {
+  /**
+   * Create a UserRole instance
+   * @param {Partial<UserRole>} [props] - User role properties
+   */
+  constructor( props ) {
+    super( props );
+    this.table = 'phase.user_roles';
+    this.prepend = 'ur';
+    this.default_columns = ['user_id', 'role_id'];
+    this.update_exclude_columns = ['user_id', 'role_id'];
+    this.base_query = `
+        SELECT ur.user_id, ur.role_id
+        FROM phase.user_roles ur
+    `;
+    this.base_list_query = this.base_query;
+    this.default_order_by = 'ORDER BY ur.user_id ASC';
+    this.instance = _props => new UserRole( _props );
+  }
+
+  /**
+   * Add a user-role relation
+   * @param {number|string} user_id - User ID
+   * @param {number|string} role_id - Role ID
+   * @returns {Promise<UserRole>} Created relation instance
+   * @throws {ValidationError} If IDs are invalid
+   * @throws {FailedToCreateError} If creation fails
+   */
+  static async add_relation( user_id, role_id ) {
+    const user_id_int = parseInt( user_id, 10 );
+    const role_id_int = parseInt( role_id, 10 );
+    if (isNaN( user_id_int ) || isNaN( role_id_int )) {
+      throw new ValidationError( 'user_id and role_id must be valid integers' );
+    }
+    const query_str = `
+        INSERT INTO phase.user_roles (user_id, role_id)
+        VALUES ($1, $2)
+        RETURNING *;
+    `;
+    const values = [user_id_int, role_id_int];
+    const result = await phsdb.query( query_str, values, { plain:true } );
+    if (!result) throw new FailedToCreateError( 'Failed to add user-role relation' );
+    return new UserRole( result );
+  }
+
+  /**
+   * Remove a user-role relation
+   * @param {number|string} role_id - Role ID
+   * @param {number|string|undefined} [user_id=undefined] - User ID
+   * @returns {Promise<UserRole|null>} Deleted relation instance or null
+   * @throws {ValidationError} If IDs are invalid
+   */
+  static async remove_relation( role_id, user_id = undefined ) {
+    const user_id_int = parseInt( user_id, 10 );
+    const role_id_int = parseInt( role_id, 10 );
+    if (isNaN( role_id_int )) {
+      throw new ValidationError( 'role_id must be a valid integer' );
+    }
+    let query_str = `
+        DELETE
+        FROM phase.user_roles
+        WHERE role_id = $1 ${ user_id_int ? 'AND user_id = $2' : '' }
+        RETURNING *;
+    `;
+    const values = [role_id_int];
+    if (!isNaN( user_id_int )) values.push( user_id_int );
+    const result = await phsdb.query( query_str, values, { plain:!isNaN( user_id_int ) } );
+    return result ? new UserRole( result ) : null;
+  }
+
+  /**
+   * Find user-role relation by IDs
+   * @param {number|string} user_id - User ID
+   * @param {number|string} role_id - Role ID
+   * @param {string[]} [excludes] - Fields to exclude from result
+   * @returns {Promise<UserRole|null>} Relation instance or null
+   */
+  static async find_by_ids( user_id, role_id, excludes = [] ) {
+    return await new UserRole().find_one(
+      { user_id, role_id },
+      excludes
+    );
+  }
+
+  /**
+   * Find user-role relations by user ID
+   * @param {number|string} user_id - User ID
+   * @param {string[]} [excludes] - Fields to exclude from result
+   * @param {{name: string, direction?: 'asc'|'desc'}||null} [order_by] - Order by configuration
+   * @param {number} [limit=100] - Maximum number of records
+   * @param {number} [offset=0] - Number of records to skip
+   * @returns {Promise<UserRole[]>} Array of relations
+   */
+  static async find_by_user_id( user_id, excludes = [], order_by = null, limit = 100, offset = 0 ) {
+    return await new UserRole().find_many(
+      { user_id },
+      excludes,
+      order_by,
+      limit,
+      offset
+    );
+  }
+}
+
+module.exports = UserRole;
\ No newline at end of file
index 70693808c3a0ba764e1736e82f7a719879fe0bc3..06332778dcb4aa41614f8d89fb28e6b9c694e454 100755 (executable)
@@ -6,11 +6,13 @@ module.exports.APIRoutes = ( passport ) => {
   router.use( '/git', require( './git.routes' )( passport ) );
   router.use( '/docker', require( './docker.routes' )( passport ) );
   router.use( '/vpn', require( './vpn.routes' )( passport ) );
-  router.use( '/users', require( './user.routes' )( passport ) );
+  router.use( '/user', require( './user.routes' )( passport ) );
   router.use( '/phone_number', require( './phone_number.routes' )( passport ) );
   router.use( '/user_phone_numbers', require( './user_phone_numbers.routes' )( passport ) );
   router.use( '/address', require( './address.routes' )( passport ) );
   router.use( '/user_addresses', require( './user_addresses.routes' )( passport ) );
   router.use( '/authentication', require( './authentication.routes' )( passport ) );
+  router.use( '/role', require( './role.routes' )( passport ) );
+  router.use( '/user_roles', require( './user_roles.routes' )( passport ) );
   return router;
 };
diff --git a/src/routes/role.routes.js b/src/routes/role.routes.js
new file mode 100644 (file)
index 0000000..2c6a2d1
--- /dev/null
@@ -0,0 +1,23 @@
+/**
+ * @file Role routes configuration
+ */
+
+const express = require( 'express' );
+const router = express.Router();
+const { validateAuth } = require( '../middleware/routeHelpers' );
+const role_controller = require( '../controllers/role.controller' );
+
+/**
+ * Configure role routes
+ * @param {Object} passport - Passport instance for authentication
+ * @returns {Object} Express router with role routes
+ */
+module.exports = ( passport ) => {
+  router.post( '/create', validateAuth( passport ), role_controller.create );
+  router.get( '/name/:name', validateAuth( passport ), role_controller.find_by_name );
+  router.get( '/:id', validateAuth( passport ), role_controller.find_one );
+  router.get( '/', validateAuth( passport ), role_controller.find_many );
+  router.put( '/:id', validateAuth( passport ), role_controller.update );
+  router.put( '/:id/soft_delete', validateAuth( passport ), role_controller.soft_delete );
+  return router;
+};
\ No newline at end of file
diff --git a/src/routes/user_roles.routes.js b/src/routes/user_roles.routes.js
new file mode 100644 (file)
index 0000000..f5661a2
--- /dev/null
@@ -0,0 +1,21 @@
+/**
+ * @file User roles routes configuration
+ */
+
+const express = require( 'express' );
+const router = express.Router();
+const { validateAuth } = require( '../middleware/routeHelpers' );
+const user_roles_controller = require( '../controllers/user_roles.controller' );
+
+/**
+ * Configure user roles routes
+ * @param {Object} passport - Passport instance for authentication
+ * @returns {Object} Express router with user roles routes
+ */
+module.exports = ( passport ) => {
+  router.post( '/add', validateAuth( passport ), user_roles_controller.add_relation );
+  router.delete( '/remove', validateAuth( passport ), user_roles_controller.remove_relation );
+  router.get( '/ids/:user_id/:role_id', validateAuth( passport ), user_roles_controller.find_by_ids );
+  router.get( '/user/:user_id', validateAuth( passport ), user_roles_controller.find_by_user_id );
+  return router;
+};
\ No newline at end of file