/*********************************************************************************************************************************************************************** * File Name: user_groups.mdl.js * Type of Program: Model * Description: Sequelize models for `user_groups` and `user_group_members` tables. * Implements a Many-to-Many self-contained group system. * Groups are used as named permission bundles. * Author: rgrgogu * Date Created: Oct. 6, 2025 *********************************************************************************************************************************************************************** * HOW TO USE: * const { mdl_UserGroups, mdl_UserGroupMembers } = require('./models/user_groups.mdl'); ***********************************************************************************************************************************************************************/ const { DataTypes } = require('sequelize'); const sequelize = require('../../config/db.config'); const mdl_Users = require('./users.mdl'); // ─── UserGroups ──────────────────────────────────────────────────────────────── const mdl_UserGroups = sequelize.define('UserGroup', { group_id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true }, name: { type: DataTypes.STRING(50), allowNull: false }, description: { type: DataTypes.TEXT }, is_active: { type: DataTypes.BOOLEAN, defaultValue: true }, // ── Audit trails ──────────────────────────────────────────────────────────── createdBy: { type: DataTypes.BIGINT, allowNull: true, label: "Created By" }, updatedBy: { type: DataTypes.BIGINT, allowNull: true, label: "Modified By" }, deletedBy: { type: DataTypes.BIGINT, allowNull: true, label: "Deleted By" }, }, { tableName: 'user_groups', timestamps: true, paranoid: true, }); // ─── Junction: UserGroupMembers ──────────────────────────────────────────────── const mdl_UserGroupMembers = sequelize.define('UserGroupMember', { group_id: { type: DataTypes.BIGINT, primaryKey: true }, user_id: { type: DataTypes.BIGINT, primaryKey: true }, joined_at: { type: DataTypes.DATE, defaultValue: DataTypes.NOW }, // ── Audit trails ──────────────────────────────────────────────────────────── createdBy: { type: DataTypes.BIGINT, allowNull: true, label: "Created By" }, updatedBy: { type: DataTypes.BIGINT, allowNull: true, label: "Modified By" }, deletedBy: { type: DataTypes.BIGINT, allowNull: true, label: "Deleted By" }, }, { tableName: 'user_group_members', timestamps: true, paranoid: true, }); // ─── Associations ────────────────────────────────────────────────────────────── mdl_Users.belongsToMany(mdl_UserGroups, { through: mdl_UserGroupMembers, foreignKey: 'user_id', otherKey: 'group_id', as: 'groups' }); mdl_UserGroups.belongsToMany(mdl_Users, { through: mdl_UserGroupMembers, foreignKey: 'group_id', otherKey: 'user_id', as: 'members', }); mdl_UserGroups.hasMany(mdl_UserGroupMembers, { foreignKey: 'group_id' }); mdl_UserGroupMembers.belongsTo(mdl_UserGroups, { foreignKey: 'group_id' }); mdl_Users.hasMany(mdl_UserGroupMembers, { foreignKey: 'user_id' }); mdl_UserGroupMembers.belongsTo(mdl_Users, { foreignKey: 'user_id' }); // models/users/user_groups.mdl.js — add at the bottom mdl_UserGroups.belongsTo(mdl_Users, { as: 'creator', foreignKey: 'createdBy' }); mdl_UserGroups.belongsTo(mdl_Users, { as: 'modifier', foreignKey: 'updatedBy' }); mdl_UserGroups.belongsTo(mdl_Users, { as: 'deleter', foreignKey: 'deletedBy' }); // Self-referencing associations for audit fields mdl_Users.belongsTo(mdl_Users, { as: 'creator', foreignKey: 'createdBy' }); mdl_Users.belongsTo(mdl_Users, { as: 'modifier', foreignKey: 'updatedBy' }); mdl_Users.belongsTo(mdl_Users, { as: 'deleter', foreignKey: 'deletedBy' }); module.exports = { mdl_UserGroups, mdl_UserGroupMembers };