Patch adding groups to project for invited users, add transactions for adding/removing groups to/from projects

This commit is contained in:
Tuan Dang
2024-04-22 11:59:17 -07:00
parent c72280e9ab
commit 0a124093d6
2 changed files with 83 additions and 75 deletions
@@ -61,7 +61,7 @@ export const userGroupMembershipDALFactory = (db: TDbClient) => {
}; };
/** /**
* Return list of users that are part of the group with id [groupId] * Return list of completed/accepted users that are part of the group with id [groupId]
* that have not yet been added individually to project with id [projectId]. * that have not yet been added individually to project with id [projectId].
* *
* Note: Filters out users that are part of other groups in the project. * Note: Filters out users that are part of other groups in the project.
@@ -69,18 +69,19 @@ export const userGroupMembershipDALFactory = (db: TDbClient) => {
* @param projectId * @param projectId
* @returns * @returns
*/ */
const findGroupMembersNotInProject = async (groupId: string, projectId: string) => { const findGroupMembersNotInProject = async (groupId: string, projectId: string, tx?: Knex) => {
try { try {
// get list of groups in the project with id [projectId] // get list of groups in the project with id [projectId]
// that that are not the group with id [groupId] // that that are not the group with id [groupId]
const groups: string[] = await db(TableName.GroupProjectMembership) const groups: string[] = await (tx || db)(TableName.GroupProjectMembership)
.where(`${TableName.GroupProjectMembership}.projectId`, projectId) .where(`${TableName.GroupProjectMembership}.projectId`, projectId)
.whereNot(`${TableName.GroupProjectMembership}.groupId`, groupId) .whereNot(`${TableName.GroupProjectMembership}.groupId`, groupId)
.pluck(`${TableName.GroupProjectMembership}.groupId`); .pluck(`${TableName.GroupProjectMembership}.groupId`);
// main query // main query
const members = await db(TableName.UserGroupMembership) const members = await (tx || db)(TableName.UserGroupMembership)
.where(`${TableName.UserGroupMembership}.groupId`, groupId) .where(`${TableName.UserGroupMembership}.groupId`, groupId)
.where(`${TableName.UserGroupMembership}.isPending`, false)
.join(TableName.Users, `${TableName.UserGroupMembership}.userId`, `${TableName.Users}.id`) .join(TableName.Users, `${TableName.UserGroupMembership}.userId`, `${TableName.Users}.id`)
.leftJoin(TableName.ProjectMembership, function () { .leftJoin(TableName.ProjectMembership, function () {
this.on(`${TableName.Users}.id`, "=", `${TableName.ProjectMembership}.userId`).andOn( this.on(`${TableName.Users}.id`, "=", `${TableName.ProjectMembership}.userId`).andOn(
@@ -32,7 +32,7 @@ type TGroupProjectServiceFactoryDep = {
TGroupProjectMembershipRoleDALFactory, TGroupProjectMembershipRoleDALFactory,
"create" | "transaction" | "insertMany" | "delete" "create" | "transaction" | "insertMany" | "delete"
>; >;
userGroupMembershipDAL: TUserGroupMembershipDALFactory; userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "findGroupMembersNotInProject">;
projectDAL: Pick<TProjectDALFactory, "findOne" | "findProjectGhostUser">; projectDAL: Pick<TProjectDALFactory, "findOne" | "findProjectGhostUser">;
projectKeyDAL: Pick<TProjectKeyDALFactory, "findLatestProjectKey" | "delete" | "insertMany" | "transaction">; projectKeyDAL: Pick<TProjectKeyDALFactory, "findLatestProjectKey" | "delete" | "insertMany" | "transaction">;
projectRoleDAL: Pick<TProjectRoleDALFactory, "find">; projectRoleDAL: Pick<TProjectRoleDALFactory, "find">;
@@ -116,16 +116,14 @@ export const groupProjectServiceFactory = ({
}, },
tx tx
); );
return groupProjectMembership;
});
// share project key with users in group that have not // share project key with users in group that have not
// individually been added to the project and that are not part of // individually been added to the project and that are not part of
// other groups that are in the project // other groups that are in the project
const groupMembers = await userGroupMembershipDAL.findGroupMembersNotInProject(group.id, project.id); const groupMembers = await userGroupMembershipDAL.findGroupMembersNotInProject(group.id, project.id, tx);
if (groupMembers.length) { if (groupMembers.length) {
const ghostUser = await projectDAL.findProjectGhostUser(project.id); const ghostUser = await projectDAL.findProjectGhostUser(project.id, tx);
if (!ghostUser) { if (!ghostUser) {
throw new BadRequestError({ throw new BadRequestError({
@@ -133,7 +131,7 @@ export const groupProjectServiceFactory = ({
}); });
} }
const ghostUserLatestKey = await projectKeyDAL.findLatestProjectKey(ghostUser.id, project.id); const ghostUserLatestKey = await projectKeyDAL.findLatestProjectKey(ghostUser.id, project.id, tx);
if (!ghostUserLatestKey) { if (!ghostUserLatestKey) {
throw new BadRequestError({ throw new BadRequestError({
@@ -141,7 +139,7 @@ export const groupProjectServiceFactory = ({
}); });
} }
const bot = await projectBotDAL.findOne({ projectId: project.id }); const bot = await projectBotDAL.findOne({ projectId: project.id }, tx);
if (!bot) { if (!bot) {
throw new BadRequestError({ throw new BadRequestError({
@@ -175,9 +173,12 @@ export const groupProjectServiceFactory = ({
}; };
}); });
await projectKeyDAL.insertMany(projectKeyData); await projectKeyDAL.insertMany(projectKeyData, tx);
} }
return groupProjectMembership;
});
return projectGroup; return projectGroup;
}; };
@@ -287,20 +288,26 @@ export const groupProjectServiceFactory = ({
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Groups); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Groups);
const groupMembers = await userGroupMembershipDAL.findGroupMembersNotInProject(group.id, project.id); const deletedProjectGroup = await groupProjectDAL.transaction(async (tx) => {
const groupMembers = await userGroupMembershipDAL.findGroupMembersNotInProject(group.id, project.id, tx);
if (groupMembers.length) { if (groupMembers.length) {
await projectKeyDAL.delete({ await projectKeyDAL.delete(
{
projectId: project.id, projectId: project.id,
$in: { $in: {
receiverId: groupMembers.map(({ user: { id } }) => id) receiverId: groupMembers.map(({ user: { id } }) => id)
} }
}); },
tx
);
} }
const [deletedGroup] = await groupProjectDAL.delete({ groupId: group.id, projectId: project.id }); const [projectGroup] = await groupProjectDAL.delete({ groupId: group.id, projectId: project.id }, tx);
return projectGroup;
});
return deletedGroup; return deletedProjectGroup;
}; };
const listGroupsInProject = async ({ const listGroupsInProject = async ({