Allow creating customers with only first or last name.

Password stays optional; missing password gets a random hash server-side.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-09-09 12:32:18 +03:30
co-authored by Cursor
parent a2dacfdc97
commit db305c58a4
2 changed files with 22 additions and 11 deletions
+13 -7
View File
@@ -499,13 +499,19 @@ export class CustomersService {
} }
} }
if (!existingUser && !dto.password) {
throw new BadRequestException('password is required for new users');
}
const passwordHash = existingUser const passwordHash = existingUser
? existingUser.passwordHash ? 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 membership = await this.prisma.$transaction(async (tx) => {
const account = const account =
@@ -515,8 +521,8 @@ export class CustomersService {
cellNumber: dto.cellNumber, cellNumber: dto.cellNumber,
passwordHash, passwordHash,
email: dto.email, email: dto.email,
firstName: dto.firstName, firstName,
lastName: dto.lastName, lastName,
firstNameEn: dto.firstNameEn?.trim() || null, firstNameEn: dto.firstNameEn?.trim() || null,
lastNameEn: dto.lastNameEn?.trim() || null, lastNameEn: dto.lastNameEn?.trim() || null,
cellVerifiedAt: new Date(), cellVerifiedAt: new Date(),
+9 -4
View File
@@ -4,6 +4,7 @@ import {
IsString, IsString,
Matches, Matches,
MinLength, MinLength,
ValidateIf,
} from 'class-validator'; } from 'class-validator';
export class CreateCustomerDto { export class CreateCustomerDto {
@@ -18,13 +19,17 @@ export class CreateCustomerDto {
@MinLength(8) @MinLength(8)
password?: string; password?: string;
/** Required when lastName is empty — at least one of first/last name must be set. */
@ValidateIf((o: CreateCustomerDto) => !o.lastName?.trim())
@IsString() @IsString()
@MinLength(2) @MinLength(1)
firstName!: string; firstName?: string;
/** Required when firstName is empty — at least one of first/last name must be set. */
@ValidateIf((o: CreateCustomerDto) => !o.firstName?.trim())
@IsString() @IsString()
@MinLength(2) @MinLength(1)
lastName!: string; lastName?: string;
@IsOptional() @IsOptional()
@IsString() @IsString()