Refactor invite user service to validate spaces and improve code structure

This commit is contained in:
faris Aljohari
2025-01-21 00:02:25 -06:00
parent 42c3f3c150
commit 9542f9334f

View File

@ -9,7 +9,7 @@ import { BaseResponseDto } from '@app/common/dto/base.response.dto';
import { UserStatusEnum } from '@app/common/constants/user-status.enum'; import { UserStatusEnum } from '@app/common/constants/user-status.enum';
import { SuccessResponseDto } from '@app/common/dto/success.response.dto'; import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
import { generateRandomString } from '@app/common/helper/randomString'; import { generateRandomString } from '@app/common/helper/randomString';
import { In, IsNull, Not, QueryRunner } from 'typeorm'; import { EntityManager, In, IsNull, Not, QueryRunner } from 'typeorm';
import { DataSource } from 'typeorm'; import { DataSource } from 'typeorm';
import { UserEntity } from '@app/common/modules/user/entities'; import { UserEntity } from '@app/common/modules/user/entities';
import { RoleType } from '@app/common/constants/role.type.enum'; import { RoleType } from '@app/common/constants/role.type.enum';
@ -69,20 +69,27 @@ export class InviteUserService {
const userRepo = queryRunner.manager.getRepository(UserEntity); const userRepo = queryRunner.manager.getRepository(UserEntity);
await this.checkEmailAndProject({ email }); await this.checkEmailAndProject({ email });
const user = await userRepo.findOne({ const existingUser = await userRepo.findOne({
where: { where: {
email, email,
project: Not(IsNull()), project: Not(IsNull()),
}, },
}); });
if (user) { if (existingUser) {
throw new HttpException( throw new HttpException(
'User already has a project', 'User already has a project',
HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST,
); );
} }
// Validate spaces
const validSpaces = await this.validateSpaces(
spaceUuids,
queryRunner.manager,
);
// Create invitation
const inviteUser = this.inviteUserRepository.create({ const inviteUser = this.inviteUserRepository.create({
firstName, firstName,
lastName, lastName,
@ -97,30 +104,25 @@ export class InviteUserService {
}); });
const invitedUser = await queryRunner.manager.save(inviteUser); const invitedUser = await queryRunner.manager.save(inviteUser);
const spaceRepo = queryRunner.manager.getRepository(SpaceEntity);
const spaces = await spaceRepo.find({
where: {
uuid: In(spaceUuids),
},
});
const spaceNames = spaces.map((space) => space.spaceName); // Link user to spaces
const spacePromises = validSpaces.map(async (space) => {
const spaceNamesString = spaceNames.join(', ');
const spacePromises = spaceUuids.map(async (spaceUuid) => {
const inviteUserSpace = this.inviteUserSpaceRepository.create({ const inviteUserSpace = this.inviteUserSpaceRepository.create({
inviteUser: { uuid: invitedUser.uuid }, inviteUser: { uuid: invitedUser.uuid },
space: { uuid: spaceUuid }, space: { uuid: space.uuid },
}); });
return queryRunner.manager.save(inviteUserSpace); return queryRunner.manager.save(inviteUserSpace);
}); });
await Promise.all(spacePromises); await Promise.all(spacePromises);
// Send invitation email
const spaceNames = validSpaces.map((space) => space.spaceName).join(', ');
await this.emailService.sendEmailWithInvitationTemplate(email, { await this.emailService.sendEmailWithInvitationTemplate(email, {
name: firstName, name: firstName,
invitationCode, invitationCode,
role: roleType, role: roleType,
spacesList: spaceNamesString, spacesList: spaceNames,
}); });
await queryRunner.commitTransaction(); await queryRunner.commitTransaction();
@ -147,6 +149,30 @@ export class InviteUserService {
await queryRunner.release(); await queryRunner.release();
} }
} }
private async validateSpaces(
spaceUuids: string[],
entityManager: EntityManager,
): Promise<SpaceEntity[]> {
const spaceRepo = entityManager.getRepository(SpaceEntity);
const validSpaces = await spaceRepo.find({
where: { uuid: In(spaceUuids) },
});
if (validSpaces.length !== spaceUuids.length) {
const validSpaceUuids = validSpaces.map((space) => space.uuid);
const invalidSpaceUuids = spaceUuids.filter(
(uuid) => !validSpaceUuids.includes(uuid),
);
throw new HttpException(
`Invalid space UUIDs: ${invalidSpaceUuids.join(', ')}`,
HttpStatus.BAD_REQUEST,
);
}
return validSpaces;
}
async checkEmailAndProject(dto: CheckEmailDto): Promise<BaseResponseDto> { async checkEmailAndProject(dto: CheckEmailDto): Promise<BaseResponseDto> {
const { email } = dto; const { email } = dto;