feat: update user passcode length, enhance date validation, and refactor personal info handling

This commit is contained in:
2026-02-01 10:02:35 +05:30
parent 745e4fa73f
commit 8ed0df7424
5 changed files with 36 additions and 24 deletions

View File

@@ -22,7 +22,7 @@ model User {
isdCode String? @map("isd_code") @db.VarChar(6) // +91, +1, +971 etc.
mobileNumber String? @unique @map("mobile_number") @db.VarChar(15) // international safe limit
userPassword String? @map("user_password") @db.VarChar(255) // hashed passwords
userPasscode String? @map("user_passcode") @db.VarChar(10) // 46 digit passcode
userPasscode String? @map("user_passcode") @db.VarChar(255) // 46 digit passcode
profileImage String? @map("profile_image") @db.VarChar(500) // S3 key or URL
userLat String? @map("user_lat") @db.VarChar(20) // "-23.44444"
userLong String? @map("user_long") @db.VarChar(20)

View File

@@ -16,7 +16,10 @@ export const userPersonalInfoSchema = z.object({
dateOfBirth: z
.string()
.nonempty("Date of birth is required"),
.nonempty("Date of birth is required")
.refine(val => !isNaN(Date.parse(val)), {
message: "Date of birth must be a valid ISO date (YYYY-MM-DD)",
}),
});

View File

@@ -1,17 +1,3 @@
export class AddPersonalInfoDTO {
firstName: string;
lastName?: string;
genderName: string;
dateOfBirth: string;
constructor(firstName: string, genderName: string, dateOfBirth: string, lastName?: string) {
this.firstName = firstName;
this.lastName = lastName;
this.genderName = genderName;
this.dateOfBirth = dateOfBirth;
}
}
export class SetPasscodeDTO {
userPasscode: string;
confirmPasscode: string;

View File

@@ -52,10 +52,12 @@ export const handler = safeHandler(async (
const validatedData = validationResult.data;
await userService.addPersonalInfo({
await userService.addPersonalInfo(userId, {
...validatedData
});
const interests = await userService.getAllInterestDetails();
return {
statusCode: 200,
headers: {
@@ -65,6 +67,7 @@ export const handler = safeHandler(async (
body: JSON.stringify({
success: true,
message: 'Personal Info added successfully',
data: interests
}),
};
});

View File

@@ -1,8 +1,8 @@
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';
import { UserPersonalInfoSchema } from '@/common/utils/validation/user/addPersonalInfo.validation';
@Injectable()
export class UserService {
constructor(private prisma: PrismaClient) { }
@@ -13,19 +13,39 @@ export class UserService {
});
}
async addPersonalInfo(data: AddPersonalInfoDTO) {
async addPersonalInfo(userId: number, data: UserPersonalInfoSchema) {
return await this.prisma.$transaction(async (tx) => {
const addPersonalInfo = await tx.user.create({
data,
const updatedUser = await tx.user.update({
where: { id: userId },
data: {
firstName: data.firstName,
lastName: data.lastName ?? null,
genderName: data.genderName,
dateOfBirth: data.dateOfBirth
? new Date(data.dateOfBirth)
: null,
isProfileUpdated: true,
},
});
if (!addPersonalInfo) {
throw new ApiError(400, 'Failed to add personal info');
return updatedUser;
});
}
async getAllInterestDetails() {
return await this.prisma.interests.findMany({
where: { isActive: true },
select: {
id: true,
interestName: true,
interestColor: true,
interestImage: true,
displayOrder: true
}
})
}
async getUserByMobileNumber(mobileNumber: string): Promise<User | null> {
return this.prisma.user.findFirst({
where: { mobileNumber: mobileNumber, isActive: true },