mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
adjusted
This commit is contained in:
@@ -7,6 +7,11 @@
|
||||
* Author: rgrgogu
|
||||
* Date Created: Oct. 6, 2025
|
||||
***********************************************************************************************************************************************************************
|
||||
* Change History:
|
||||
* DATE AUTHOR LOG DESCRIPTION
|
||||
* Oct. 6, 2025 rgrgogu 001 Initial creation - STAR Phase 1
|
||||
* May 23, 2026 rgrgogu 002 Added group_code — unique invite code for self-registration
|
||||
***********************************************************************************************************************************************************************
|
||||
* HOW TO USE:
|
||||
* const { mdl_UserGroups, mdl_UserGroupMembers } = require('./models/user_groups.mdl');
|
||||
***********************************************************************************************************************************************************************/
|
||||
@@ -16,10 +21,17 @@ const mdl_Users = require('./users.mdl');
|
||||
|
||||
// ─── UserGroups ────────────────────────────────────────────────────────────────
|
||||
const mdl_UserGroups = sequelize.define('UserGroup', {
|
||||
group_id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true, label: "Group ID", order: 1, hidden: true },
|
||||
name: { type: DataTypes.STRING(50), allowNull: false, label: "Group Name", order: 2 },
|
||||
description: { type: DataTypes.TEXT, label: "Description", order: 3, hidden: true },
|
||||
is_active: { type: DataTypes.BOOLEAN, defaultValue: true, label: "Active", order: 4 },
|
||||
group_id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true, label: "Group ID", order: 1, hidden: true },
|
||||
name: { type: DataTypes.STRING(50), allowNull: false, label: "Group Name", order: 2 },
|
||||
/**
|
||||
* group_code — unique, human-readable invite code distributed to users.
|
||||
* Used in the self-registration URL: /register?group_code=<value>
|
||||
* Automatically uppercased via a beforeValidate hook below.
|
||||
* Example: "SALES-2025", "ONBOARD-Q1"
|
||||
*/
|
||||
group_code: { type: DataTypes.STRING(50), allowNull: true, unique: true, label: "Group Code", order: 3 },
|
||||
description:{ type: DataTypes.TEXT, label: "Description", order: 4, hidden: true },
|
||||
is_active: { type: DataTypes.BOOLEAN, defaultValue: true, label: "Active", order: 5 },
|
||||
|
||||
// ── Audit trails ────────────────────────────────────────────────────────────
|
||||
createdBy: { type: DataTypes.BIGINT, allowNull: true, label: "Created By" },
|
||||
@@ -28,14 +40,20 @@ const mdl_UserGroups = sequelize.define('UserGroup', {
|
||||
}, {
|
||||
tableName: 'user_groups',
|
||||
timestamps: true,
|
||||
paranoid: true,
|
||||
paranoid: true,
|
||||
hooks: {
|
||||
// Always store group_code in uppercase to make lookups case-insensitive
|
||||
beforeValidate: (group) => {
|
||||
if (group.group_code) group.group_code = group.group_code.toUpperCase().trim();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// ─── 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 },
|
||||
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" },
|
||||
@@ -44,12 +62,12 @@ const mdl_UserGroupMembers = sequelize.define('UserGroupMember', {
|
||||
}, {
|
||||
tableName: 'user_group_members',
|
||||
timestamps: true,
|
||||
paranoid: 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_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' });
|
||||
@@ -57,14 +75,12 @@ 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' });
|
||||
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' });
|
||||
mdl_Users.belongsTo(mdl_Users, { as: 'deleter', foreignKey: 'deletedBy' });
|
||||
|
||||
module.exports = { mdl_UserGroups, mdl_UserGroupMembers };
|
||||
Reference in New Issue
Block a user