@tomei/sso
Version:
Tomei SSO Package
507 lines (469 loc) • 20.1 kB
text/typescript
import { Op, Transaction } from 'sequelize';
import { ClassError, ObjectBase } from '@tomei/general';
import { GroupReportingUserRepository } from './group-reporting-user.repository';
import { IGroupReportingUserAttr } from '../../interfaces/group-reporting-user.interface';
import { User } from '../login-user/user';
import UserModel from '../../models/user.entity';
import { Group } from '../group/group';
import { ApplicationConfig } from '@tomei/config';
import { ActionEnum, Activity } from '@tomei/activity-history';
export class GroupReportingUser extends ObjectBase {
ObjectId: string;
ObjectName: string;
TableName = 'sso_GroupReportingUser';
ObjectType = 'GroupReportingUser';
GroupReportingUserId: number;
GroupCode: string;
UserId: number;
Rank: number;
Status: string;
private _CreatedById: number;
private _CreatedAt: Date;
private _UpdatedById: number;
private _UpdatedAt: Date;
private static _Repo = new GroupReportingUserRepository();
get CreatedById(): number {
return this._CreatedById;
}
get CreatedAt(): Date {
return this._CreatedAt;
}
get UpdatedById(): number {
return this._UpdatedById;
}
get UpdatedAt(): Date {
return this._UpdatedAt;
}
private constructor(groupReportingUserAttr?: IGroupReportingUserAttr) {
super();
if (groupReportingUserAttr) {
this.GroupReportingUserId = groupReportingUserAttr.GroupReportingUserId;
this.GroupCode = groupReportingUserAttr.GroupCode;
this.UserId = groupReportingUserAttr?.UserId;
this.Rank = groupReportingUserAttr?.Rank;
this.Status = groupReportingUserAttr?.Status;
this._CreatedById = groupReportingUserAttr.CreatedById;
this._CreatedAt = groupReportingUserAttr.CreatedAt;
this._UpdatedById = groupReportingUserAttr.UpdatedById;
this._UpdatedAt = groupReportingUserAttr.UpdatedAt;
}
}
public static async init(dbTransaction: any, GroupReportingUserId?: string) {
try {
if (GroupReportingUserId) {
const groupReportingUser = await GroupReportingUser._Repo.findByPk(
GroupReportingUserId,
{
transaction: dbTransaction,
},
);
if (groupReportingUser) {
return new GroupReportingUser(groupReportingUser);
} else {
throw new ClassError(
'GroupReportingUser',
'GroupReportingUserErrMsg00',
'GroupReportingUser Not Found',
'init',
404,
);
}
}
return new GroupReportingUser();
} catch (error) {
throw error;
}
}
async createGroupReportingUser(
loginUser: User, //The user performing the operation(typically the logged -in user).
dbTransaction: any, //Database transaction object to ensure the operation is atomic.
groupCode: string, //The code of the group to which the user is being assigned.
userId: number, //The ID of the user to be added to the group.
rank: number, //The rank to be assigned to the user in the group.
status: 'Active' | 'Inactive', //The initial status of the user in the group.
): Promise<GroupReportingUser> {
// Returns a GroupReportingUser instance representing the newly created record.
try {
//Creates a new group reporting user entry in the sso_GroupReportingUser table.
// Validate Input Parameters
// Ensure groupCode exists in the sso_Group table by calling the Group.init() method.
const group = await Group.init(dbTransaction, groupCode);
// Ensure userId exists in the sso_User table by calling the User.init() method.
const user = await User.init(dbTransaction, userId);
// Privilege Checking
// Call the loginUser.checkPrivileges() method by passing:
// SystemCode: Retrieve from app config.
// PrivilegeCode: "GROUP_REPORTING_USER_CREATE".
const systemCode =
ApplicationConfig.getComponentConfigValue('system-code');
const isPrivileged = await loginUser.checkPrivileges(
systemCode,
'GROUP_REPORTING_USER_CREATE',
);
if (!isPrivileged) {
throw new ClassError(
'GroupReportingUser',
'GroupReportingUserErrMsg02',
'Insufficient privileges to add a user to the group',
);
}
// Check for Duplicate User in Group
// Query the sso_GroupReportingUser table to see if the userId already exists in the specified groupCode.
const groupReportingUser = await GroupReportingUser._Repo.findOne({
where: {
GroupCode: groupCode,
UserId: userId,
},
transaction: dbTransaction,
});
// If the user already exists in the group, throw an error indicating the user is already part of the group.
if (groupReportingUser) {
throw new ClassError(
'GroupReportingUser',
'GroupReportingUserErrMsg03',
'User already exists in the group',
'createGroupReportingUser',
);
}
//Query the sso_GroupReportingUser table to see if the rank already exists in the specified groupCode.
//If the rank already exists in the group, throw an error indicating the rank is already in of the group.
const groupReportingUserRank = await GroupReportingUser._Repo.findOne({
where: {
GroupCode: groupCode,
Rank: rank,
},
transaction: dbTransaction,
});
if (groupReportingUserRank) {
throw new ClassError(
'GroupReportingUser',
'GroupReportingUserErrMsg04',
'Rank already exists in the group',
'createGroupReportingUser',
);
}
// Create GroupReportingUser Entry
// If validation and privilege checks pass, insert a new record in the sso_GroupReportingUser table with the provided groupCode, userId, rank, status, and loginUser.UserId.Automatically capture the current timestamp for CreatedAt.
this.GroupCode = groupCode;
this.UserId = userId;
this.Rank = rank;
this.Status = status;
this._CreatedById = loginUser.UserId;
this._CreatedAt = new Date();
this._UpdatedAt = new Date();
this._UpdatedById = loginUser.UserId;
const entityValueAfter: any = {
GroupCode: groupCode,
UserId: userId,
Rank: rank,
Status: status,
CreatedById: loginUser.UserId,
CreatedAt: this._CreatedAt,
UpdatedById: loginUser.UserId,
UpdatedAt: this._UpdatedAt,
};
const newGroupReportingUser = await GroupReportingUser._Repo.create(
entityValueAfter,
{
transaction: dbTransaction,
},
);
entityValueAfter.GroupReportingUserId =
newGroupReportingUser.GroupReportingUserId;
// Record Create Activity
// Instantiate a new activity from the Activity class, and set:\
// ActivityId: activity.createId()
// Action: ActionEnum.Create
// Description: Create Group Reporting User
// EntityType: GroupReportingUser
// EntityId: newGroupReportingUser.GroupReportingUserId
// EntityValueBefore: Stringified empty object({})
// EntityValueAfter: EntityValueAfter(stringified representation of the newly created entity)
const activity = new Activity();
activity.ActivityId = activity.createId();
activity.Action = ActionEnum.CREATE;
activity.Description = 'Create Group Reporting User';
activity.EntityType = 'GroupReportingUser';
activity.EntityId = newGroupReportingUser.GroupReportingUserId.toString();
activity.EntityValueBefore = JSON.stringify({});
activity.EntityValueAfter = JSON.stringify(entityValueAfter);
// Call the activity create() method by passing:
// dbTransaction
// userId: loginUser.UserId
await activity.create(loginUser.ObjectId, dbTransaction);
// Return the Created GroupReportingUser
// Return the newly created GroupReportingUser instance, including all the relevant details like GroupReportingUserId, groupCode, userId, rank, status, and timestamps for CreatedAt.
return this;
} catch (error) {
throw error;
}
}
async updateGroupReportingUser(
loginUser: User, //The user performing the operation(typically the logged -in user).
dbTransaction: any, //Database transaction object to ensure the operation is atomic.
groupCode: string, //The code of the group to which the user is being assigned.
userId: number, //The ID of the user to be added to the group.
rank: number, //The rank to be assigned to the user in the group.
status: 'Active' | 'Inactive', //The initial status of the user in the group.
): Promise<GroupReportingUser> {
// Returns a GroupReportingUser instance representing the updated record.
try {
//Update a group reporting user entry in the sso_GroupReportingUser table.
// Validate Input Parameters
// Ensure groupCode exists in the sso_Group table by calling the Group.init() method.
await Group.init(dbTransaction, groupCode);
// Ensure userId exists in the sso_User table by calling the User.init() method.
await User.init(dbTransaction, userId);
// Privilege Checking
// Call the loginUser.checkPrivileges() method by passing:
// SystemCode: Retrieve from app config.
// PrivilegeCode: "GROUP_REPORTING_USER_UPDATE".
const systemCode =
ApplicationConfig.getComponentConfigValue('system-code');
const isPrivileged = await loginUser.checkPrivileges(
systemCode,
'GROUP_REPORTING_USER_UPDATE',
);
if (!isPrivileged) {
throw new ClassError(
'GroupReportingUser',
'GroupReportingUserErrMsg02',
'Insufficient privileges to update a user to the group',
);
}
//Get the current groupReportingUser
const currentGroupReportingUser = await GroupReportingUser._Repo.findOne({
where: {
GroupCode: groupCode,
GroupReportingUserId: this.GroupReportingUserId,
},
transaction: dbTransaction,
});
// Check for Duplicate User in Group
// Query the sso_GroupReportingUser table to see if the userId already exists in the specified groupCode.
const groupReportingUser = await GroupReportingUser._Repo.findOne({
where: {
GroupCode: groupCode,
UserId: userId,
GroupReportingUserId: {
[Op.ne]: this.GroupReportingUserId,
},
},
transaction: dbTransaction,
});
// If the user already exists in the group, throw an error indicating the user is already part of the group.
if (groupReportingUser) {
throw new ClassError(
'GroupReportingUser',
'GroupReportingUserErrMsg03',
'User already exists in the group',
'updateGroupReportingUser',
);
}
//Query the sso_GroupReportingUser table to see if the rank already exists in the specified groupCode.
//If the rank already exists in the group, throw an error indicating the rank is already in of the group.
const groupReportingUserRank = await GroupReportingUser._Repo.findOne({
where: {
GroupCode: groupCode,
Rank: rank,
GroupReportingUserId: {
[Op.ne]: this.GroupReportingUserId,
},
},
transaction: dbTransaction,
});
if (groupReportingUserRank) {
throw new ClassError(
'GroupReportingUser',
'GroupReportingUserErrMsg04',
'Rank already exists in the group',
'updateGroupReportingUser',
);
}
// UPDATE GroupReportingUser Entry
// If validation and privilege checks pass, insert a new record in the sso_GroupReportingUser table with the provided groupCode, userId, rank, status, and loginUser.UserId.Automatically capture the current timestamp for CreatedAt.
this.GroupCode = groupCode;
this.UserId = userId;
this.Rank = rank;
this.Status = status;
this._CreatedById = currentGroupReportingUser.CreatedById;
this._CreatedAt = currentGroupReportingUser.CreatedAt;
this._UpdatedAt = new Date();
this._UpdatedById = loginUser.UserId;
const entityValueAfter: any = {
GroupCode: groupCode,
UserId: userId,
Rank: rank,
Status: status,
CreatedById: currentGroupReportingUser.CreatedById,
CreatedAt: this._CreatedAt,
UpdatedById: loginUser.UserId,
UpdatedAt: this._UpdatedAt,
};
await GroupReportingUser._Repo.update(entityValueAfter, {
where: {
GroupReportingUserId: this.GroupReportingUserId,
},
transaction: dbTransaction,
});
// Record Update Activity
// Instantiate a new activity from the Activity class, and set:\
// ActivityId: activity.createId()
// Action: ActionEnum.Update
// Description: Update Group Reporting User
// EntityType: GroupReportingUser
// EntityId: newGroupReportingUser.GroupReportingUserId
// EntityValueBefore: Stringified empty object({})
// EntityValueAfter: EntityValueAfter(stringified representation of the newly created entity)
const activity = new Activity();
activity.ActivityId = activity.createId();
activity.Action = ActionEnum.UPDATE;
activity.Description = 'Update Group Reporting User';
activity.EntityType = 'GroupReportingUser';
activity.EntityId = this.GroupReportingUserId.toString();
activity.EntityValueBefore = JSON.stringify({});
activity.EntityValueAfter = JSON.stringify(entityValueAfter);
// Call the activity create() method by passing:
// dbTransaction
// userId: loginUser.UserId
await activity.create(loginUser.ObjectId, dbTransaction);
// Return the Updated GroupReportingUser
// Return the updated GroupReportingUser instance, including all the relevant details like GroupReportingUserId, groupCode, userId, rank, status, and timestamps for CreatedAt.
return this;
} catch (error) {
throw error;
}
}
public static async findAllGroupReportingUsers(
loginUser: User, //The authenticated user requesting the information.
dbTransaction: any, //The database transaction to be used for this operation.
groupCode?: string, //The code of the group whose reporting users should be retrieved.
) {
//This public static method retrieves all GroupReportingUser records for a given group from the sso_GroupReportingUser table.
try {
// Part 1: Privilege Check
// Call loginUser.checkPrivileges() method by passing:
// - SystemCode: Retrieve from the app config.
// - PrivilegeCode: GROUP_REPORTING_USER_VIEW.
// If the user does not have the required privilege, throw a ForbiddenError.
const systemCode =
ApplicationConfig.getComponentConfigValue('system-code');
const isPrivileged = await loginUser.checkPrivileges(
systemCode,
'GROUP_REPORTING_USER_VIEW',
);
if (!isPrivileged) {
throw new ClassError(
'Group',
'GroupReportingUserErrMsg05',
'You do not have the privilege to view group reporting user',
);
}
// Part 2: Group Existence Check
// Call Group.init(dbTransaction, groupCode) to verify the group exists.
// If the group does not exist, throw a NotFoundError.
await Group.init(dbTransaction, groupCode);
// Part 3: Retrieve Group Reporting Users
// Call GroupReportingUser._Repo.findAll() to retrieve all users associated with the provided groupCode.
// The users should be sorted by Rank in ascending order (Rank 1, Rank 2, and so on).
// Ensure the query is performed within the dbTransaction.
const result = await GroupReportingUser._Repo.findAll({
where: {
GroupCode: groupCode,
},
include: [
{
model: UserModel,
as: 'User',
},
],
order: [
['Rank', 'ASC'], // or 'DESC' for descending order
],
transaction: dbTransaction,
});
// Part 4: Return Results
// Return the array of GroupReportingUser records found.
return result;
} catch (error) {
// Part 5: Handle Errors
// Catch and handle any errors during the execution. If an error occurs, ensure the transaction is rolled back.
throw error;
}
}
public static async removeGroupReportingUser(
loginUser: User, //The user performing the operation, used for privilege checking and logging.
dbTransaction: Transaction, // The database transaction object to ensure the operation's atomicity.
groupReportingUserId: number, //The ID of the GroupReportingUser to be removed.
): Promise<void> {
// This method removes a GroupReportingUser record from the database.
try {
// Part 1: Privilege Checking
// Call loginUser.checkPrivileges() method by passing:
// SystemCode: Retrieve from app config.
// PrivilegeCode: "GROUP_REPORTING_USER_REMOVE".
const systemCode =
ApplicationConfig.getComponentConfigValue('system-code');
const isPrivileged = await loginUser.checkPrivileges(
systemCode,
'GROUP_REPORTING_USER_REMOVE',
);
if (!isPrivileged) {
throw new ClassError(
'GroupReportingUser',
'GroupReportingUserErrMsg06',
'Insufficient privileges to remove a user from the group',
'removeGroupReportingUser',
403,
);
}
// Part 2: Find User
// Call GroupReportingUser.init(dbTransaction, groupReportingUserId) to check if the user exists.
const groupReportingUser = await GroupReportingUser.init(
dbTransaction,
groupReportingUserId.toString(),
);
// Part 3: Remove User
// Call GroupReportingUser._Repo.destroy({ where: { GroupReportingUserId: groupReportingUserId }, transaction: dbTransaction }) to remove the user from the database.
await GroupReportingUser._Repo.destroy(
groupReportingUserId,
dbTransaction,
);
// Part 4: Record Create Activity
// Initialise EntityValueBefore variable and set it to the GroupReportingUser instance before destruction.
const entityValueBefore = {
GroupReportingUserId: groupReportingUser.GroupReportingUserId,
GroupCode: groupReportingUser.GroupCode,
UserId: groupReportingUser.UserId,
Rank: groupReportingUser.Rank,
Status: groupReportingUser.Status,
CreatedById: groupReportingUser.CreatedById,
CreatedAt: groupReportingUser.CreatedAt,
UpdatedById: groupReportingUser.UpdatedById,
UpdatedAt: groupReportingUser.UpdatedAt,
};
// Instantiate a new activity from the Activity class, and set:
const activity = new Activity();
// ActivityId: activity.createId()
// Action: ActionEnum.Delete
// Description: Remove Group Reporting User
// EntityType: GroupReportingUser
// EntityId: groupReportingUserId
// EntityValueBefore: Stringified representation of the GroupReportingUser instance before destroy
// EntityValueAfter: Stringified empty object ({})
activity.ActivityId = activity.createId();
activity.Action = ActionEnum.DELETE;
activity.Description = 'Remove Group Reporting User';
activity.EntityType = 'GroupReportingUser';
activity.EntityId = groupReportingUserId.toString();
activity.EntityValueBefore = JSON.stringify(entityValueBefore);
activity.EntityValueAfter = JSON.stringify({});
// Call the activity.create() method by passing:
// dbTransaction
// userId: loginUser.UserId
await activity.create(loginUser.ObjectId, dbTransaction);
} catch (error) {
throw error;
}
}
}