Add project permission cache

This commit is contained in:
Carlos Monastyrski
2025-09-23 17:15:54 -03:00
parent 362abc44d6
commit 4eee40c2a3
12 changed files with 345 additions and 30 deletions
@@ -37,13 +37,19 @@ type TGroupProjectServiceFactoryDep = {
TGroupProjectMembershipRoleDALFactory,
"create" | "transaction" | "insertMany" | "delete"
>;
userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "findGroupMembersNotInProject">;
userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "findGroupMembersNotInProject" | "find">;
projectDAL: Pick<TProjectDALFactory, "findOne" | "findProjectGhostUser" | "findById">;
projectKeyDAL: Pick<TProjectKeyDALFactory, "findLatestProjectKey" | "delete" | "insertMany" | "transaction">;
projectRoleDAL: Pick<TProjectRoleDALFactory, "find">;
projectBotDAL: TProjectBotDALFactory;
groupDAL: Pick<TGroupDALFactory, "findOne" | "findAllGroupPossibleMembers">;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getProjectPermissionByRole">;
permissionService: Pick<
TPermissionServiceFactory,
| "getProjectPermission"
| "getProjectPermissionByRole"
| "invalidateProjectPermissionCache"
| "invalidateUserProjectPermissionCache"
>;
};
export type TGroupProjectServiceFactory = ReturnType<typeof groupProjectServiceFactory>;
@@ -263,6 +269,12 @@ export const groupProjectServiceFactory = ({
return groupProjectMembership;
});
const groupMembers = await userGroupMembershipDAL.find({ groupId: group.id });
await Promise.allSettled([
permissionService.invalidateProjectPermissionCache(projectId),
...groupMembers.map((member) => permissionService.invalidateUserProjectPermissionCache(member.userId))
]);
return projectGroup;
};
@@ -372,6 +384,12 @@ export const groupProjectServiceFactory = ({
return groupProjectMembershipRoleDAL.insertMany(sanitizedProjectMembershipRoles, tx);
});
const groupMembers = await userGroupMembershipDAL.find({ groupId });
await Promise.allSettled([
permissionService.invalidateProjectPermissionCache(projectId),
...groupMembers.map((member) => permissionService.invalidateUserProjectPermissionCache(member.userId))
]);
return updatedRoles;
};
@@ -403,15 +421,21 @@ export const groupProjectServiceFactory = ({
});
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Delete, ProjectPermissionSub.Groups);
const deletedProjectGroup = await groupProjectDAL.transaction(async (tx) => {
const groupMembers = await userGroupMembershipDAL.findGroupMembersNotInProject(group.id, project.id, tx);
const groupMembers = await userGroupMembershipDAL.find({ groupId: group.id });
if (groupMembers.length) {
const deletedProjectGroup = await groupProjectDAL.transaction(async (tx) => {
const groupMembersNotInProject = await userGroupMembershipDAL.findGroupMembersNotInProject(
group.id,
project.id,
tx
);
if (groupMembersNotInProject.length) {
await projectKeyDAL.delete(
{
projectId: project.id,
$in: {
receiverId: groupMembers.map(({ user: { id } }) => id)
receiverId: groupMembersNotInProject.map(({ user: { id } }) => id)
}
},
tx
@@ -422,6 +446,11 @@ export const groupProjectServiceFactory = ({
return projectGroup;
});
await Promise.allSettled([
permissionService.invalidateProjectPermissionCache(projectId),
...groupMembers.map((member) => permissionService.invalidateUserProjectPermissionCache(member.userId))
]);
return deletedProjectGroup;
};