mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-08-25 21:59:40 +00:00
127 lines
4.9 KiB
TypeScript
127 lines
4.9 KiB
TypeScript
import { BadRequestException, forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
|
|
import { FindOptionsWhere } from 'typeorm';
|
|
import { Transactional } from 'typeorm-transactional';
|
|
import { CustomerService } from '~/customer/services';
|
|
import { CreateUnverifiedUserRequestDto } from '../../auth/dtos/request';
|
|
import { Roles } from '../../auth/enums';
|
|
import { User } from '../entities';
|
|
import { UserRepository } from '../repositories';
|
|
|
|
@Injectable()
|
|
export class UserService {
|
|
private readonly logger = new Logger(UserService.name);
|
|
constructor(
|
|
private readonly userRepository: UserRepository,
|
|
@Inject(forwardRef(() => CustomerService)) private readonly customerService: CustomerService,
|
|
) {}
|
|
|
|
findUser(where: FindOptionsWhere<User> | FindOptionsWhere<User>[]) {
|
|
this.logger.log(`finding user with where clause ${JSON.stringify(where)}`);
|
|
return this.userRepository.findOne(where);
|
|
}
|
|
|
|
async findUserOrThrow(where: FindOptionsWhere<User>) {
|
|
this.logger.log(`Finding user with where clause ${JSON.stringify(where)}`);
|
|
const user = await this.findUser(where);
|
|
|
|
if (!user) {
|
|
this.logger.error(`User with not found with where clause ${JSON.stringify(where)}`);
|
|
throw new BadRequestException('USER.NOT_FOUND');
|
|
}
|
|
|
|
this.logger.log(`User with where clause ${JSON.stringify(where)} found successfully`);
|
|
return user;
|
|
}
|
|
|
|
async findOrCreateUser({ phoneNumber, countryCode }: CreateUnverifiedUserRequestDto) {
|
|
this.logger.log(`Finding or creating user with phone number ${phoneNumber} and country code ${countryCode}`);
|
|
const user = await this.userRepository.findOne({ phoneNumber });
|
|
|
|
if (!user) {
|
|
this.logger.log(`User with phone number ${phoneNumber} not found, creating new user`);
|
|
return this.userRepository.createUnverifiedUser({ phoneNumber, countryCode, roles: [Roles.GUARDIAN] });
|
|
}
|
|
if (user && user.roles.includes(Roles.GUARDIAN) && user.isProfileCompleted) {
|
|
this.logger.error(`User with phone number ${phoneNumber} already exists`);
|
|
throw new BadRequestException('USER.PHONE_NUMBER_ALREADY_EXISTS');
|
|
}
|
|
|
|
if (user && user.roles.includes(Roles.JUNIOR)) {
|
|
this.logger.error(`User with phone number ${phoneNumber} is an already registered junior`);
|
|
throw new BadRequestException('USER.JUNIOR_UPGRADE_NOT_SUPPORTED_YET');
|
|
//TODO add role Guardian to the existing user and send OTP
|
|
}
|
|
|
|
this.logger.log(`User with phone number ${phoneNumber} and country code ${countryCode} found successfully`);
|
|
return user;
|
|
}
|
|
|
|
async createUser(data: Partial<User>) {
|
|
this.logger.log(`Creating user with data ${JSON.stringify(data)}`);
|
|
const user = await this.userRepository.createUser(data);
|
|
|
|
this.logger.log(`User with data ${JSON.stringify(data)} created successfully`);
|
|
return user;
|
|
}
|
|
|
|
setEmail(userId: string, email: string) {
|
|
this.logger.log(`Setting email ${email} for user ${userId}`);
|
|
return this.userRepository.update(userId, { email });
|
|
}
|
|
|
|
setPasscode(userId: string, passcode: string, salt: string) {
|
|
this.logger.log(`Setting passcode for user ${userId}`);
|
|
return this.userRepository.update(userId, { password: passcode, salt, isProfileCompleted: true });
|
|
}
|
|
|
|
setPhoneNumber(userId: string, phoneNumber: string, countryCode: string) {
|
|
this.logger.log(`Setting phone number ${phoneNumber} for user ${userId}`);
|
|
return this.userRepository.update(userId, { phoneNumber, countryCode });
|
|
}
|
|
|
|
verifyPhoneNumber(userId: string) {
|
|
this.logger.log(`Verifying phone number for user ${userId}`);
|
|
return this.userRepository.update(userId, { isPhoneVerified: true });
|
|
}
|
|
|
|
@Transactional()
|
|
async createGoogleUser(googleId: string, email: string) {
|
|
this.logger.log(`Creating google user with googleId ${googleId} and email ${email}`);
|
|
const user = await this.userRepository.createUser({
|
|
googleId,
|
|
email,
|
|
roles: [Roles.GUARDIAN],
|
|
isEmailVerified: true,
|
|
});
|
|
|
|
await this.customerService.createGuardianCustomer(user.id);
|
|
|
|
return this.findUserOrThrow({ id: user.id });
|
|
}
|
|
|
|
@Transactional()
|
|
async createAppleUser(appleId: string, email: string) {
|
|
this.logger.log(`Creating apple user with appleId ${appleId} and email ${email}`);
|
|
const user = await this.userRepository.createUser({
|
|
appleId,
|
|
email,
|
|
roles: [Roles.GUARDIAN],
|
|
isEmailVerified: true,
|
|
});
|
|
|
|
await this.customerService.createGuardianCustomer(user.id);
|
|
|
|
return this.findUserOrThrow({ id: user.id });
|
|
}
|
|
|
|
@Transactional()
|
|
async verifyUserAndCreateCustomer(userId: string) {
|
|
this.logger.log(`Verifying user ${userId} and creating customer`);
|
|
await this.userRepository.update(userId, { isPhoneVerified: true });
|
|
await this.customerService.createGuardianCustomer(userId);
|
|
|
|
this.logger.log(`User ${userId} verified and customer created successfully`);
|
|
return this.findUserOrThrow({ id: userId });
|
|
}
|
|
}
|