From db305c58a4b55815470cb66ba0c9de4f843d7ded Mon Sep 17 00:00:00 2001 From: Alireza Hassani Date: Wed, 9 Sep 2026 12:32:18 +0330 Subject: [PATCH] Allow creating customers with only first or last name. Password stays optional; missing password gets a random hash server-side. Co-authored-by: Cursor --- src/customers/customers.service.ts | 20 +++++++++++++------- src/customers/dto/create-customer.dto.ts | 13 +++++++++---- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/customers/customers.service.ts b/src/customers/customers.service.ts index cf0da2f..1d47094 100644 --- a/src/customers/customers.service.ts +++ b/src/customers/customers.service.ts @@ -499,13 +499,19 @@ export class CustomersService { } } - if (!existingUser && !dto.password) { - throw new BadRequestException('password is required for new users'); - } - const passwordHash = existingUser ? existingUser.passwordHash - : await bcrypt.hash(dto.password!, 10); + : await bcrypt.hash( + // Password optional: random unusable hash when omitted (OTP login still works). + dto.password?.trim() || randomBytes(32).toString('hex'), + 10, + ); + + const firstName = dto.firstName?.trim() || null; + const lastName = dto.lastName?.trim() || null; + if (!firstName && !lastName) { + throw new BadRequestException('firstName or lastName is required'); + } const membership = await this.prisma.$transaction(async (tx) => { const account = @@ -515,8 +521,8 @@ export class CustomersService { cellNumber: dto.cellNumber, passwordHash, email: dto.email, - firstName: dto.firstName, - lastName: dto.lastName, + firstName, + lastName, firstNameEn: dto.firstNameEn?.trim() || null, lastNameEn: dto.lastNameEn?.trim() || null, cellVerifiedAt: new Date(), diff --git a/src/customers/dto/create-customer.dto.ts b/src/customers/dto/create-customer.dto.ts index 0e1adb5..ad422f2 100644 --- a/src/customers/dto/create-customer.dto.ts +++ b/src/customers/dto/create-customer.dto.ts @@ -4,6 +4,7 @@ import { IsString, Matches, MinLength, + ValidateIf, } from 'class-validator'; export class CreateCustomerDto { @@ -18,13 +19,17 @@ export class CreateCustomerDto { @MinLength(8) password?: string; + /** Required when lastName is empty — at least one of first/last name must be set. */ + @ValidateIf((o: CreateCustomerDto) => !o.lastName?.trim()) @IsString() - @MinLength(2) - firstName!: string; + @MinLength(1) + firstName?: string; + /** Required when firstName is empty — at least one of first/last name must be set. */ + @ValidateIf((o: CreateCustomerDto) => !o.firstName?.trim()) @IsString() - @MinLength(2) - lastName!: string; + @MinLength(1) + lastName?: string; @IsOptional() @IsString()