import { Injectable } from '@nestjs/common'; import { PrismaClient, User } from '@prisma/client'; import { AddPersonalInfoDTO } from '../dto/user.dto'; import ApiError from '@/common/utils/helper/ApiError'; import * as bcrypt from 'bcryptjs'; @Injectable() export class UserService { constructor(private prisma: PrismaClient) { } async getUserById(userId: number) { return this.prisma.user.findUnique({ where: { id: userId, isActive: true }, }); } async addPersonalInfo(data: AddPersonalInfoDTO) { return await this.prisma.$transaction(async (tx) => { const addPersonalInfo = await tx.user.create({ data, }); if (!addPersonalInfo) { throw new ApiError(400, 'Failed to add personal info'); } }) } async getUserByMobileNumber(mobileNumber: string): Promise { return this.prisma.user.findFirst({ where: { mobileNumber: mobileNumber, isActive: true }, }); } async verifyHostOtp(mobileNumber: string, otp: string): Promise { const user = await this.prisma.user.findFirst({ where: { mobileNumber: mobileNumber, isActive: true }, select: { id: true, mobileNumber: true, UserOtp: { where: { isActive: true, isVerified: false }, orderBy: { createdAt: 'desc' }, take: 1, }, }, }); if (!user) { throw new ApiError(404, 'User not found.'); } const userOtp = user.UserOtp[0]; if (!userOtp) { throw new ApiError(400, 'No OTP found.'); } if (new Date() > userOtp.expiresOn) { throw new ApiError(400, 'OTP has expired.'); } const isMatch = await bcrypt.compare(otp, userOtp.otpCode); if (!isMatch) { throw new ApiError(400, 'Invalid OTP.'); } await this.prisma.userOtp.update({ where: { id: userOtp.id }, data: { isVerified: true, verifiedOn: new Date(), isActive: false, }, }); return true; } }