From be273ea5f4e47acd3bce67882f93ad10d97394e0 Mon Sep 17 00:00:00 2001 From: Ronni Baslund Date: Sun, 24 May 2026 22:23:27 +0200 Subject: [PATCH] fix(partners): allow empty-string email fields on partial updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @IsOptional() only skips validation for null/undefined; an empty string still trips @IsEmail(). When the operator UI saves billingInfo with a blank contactEmail, the request 400'd with 'must be an email'. Coerce '' → undefined on every @IsEmail-decorated field via a shared @Transform so blank inputs round-trip cleanly. --- .../src/partners/dto/update-partner.dto.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/services/platform-api/src/partners/dto/update-partner.dto.ts b/services/platform-api/src/partners/dto/update-partner.dto.ts index 99a9a1c..98fdb91 100644 --- a/services/platform-api/src/partners/dto/update-partner.dto.ts +++ b/services/platform-api/src/partners/dto/update-partner.dto.ts @@ -1,4 +1,4 @@ -import { Type } from 'class-transformer' +import { Transform, Type } from 'class-transformer' import { IsEmail, IsEnum, @@ -12,17 +12,25 @@ import { ValidateNested, } from 'class-validator' +// Coerce '' → undefined so blank form fields don't trip @IsEmail on the +// nested DTOs. @IsOptional() skips validation only for null/undefined, not +// empty strings — without this transform a partial edit fails the moment +// the form contains an unfilled email field. +const EmptyToUndefined = Transform(({ value }: { value: unknown }) => + value === '' ? undefined : value, +) + class ContactInfoDto { @IsOptional() @IsString() @MaxLength(200) primaryName?: string - @IsOptional() @IsEmail() primaryEmail?: string - @IsOptional() @IsEmail() billingEmail?: string + @EmptyToUndefined @IsOptional() @IsEmail() primaryEmail?: string + @EmptyToUndefined @IsOptional() @IsEmail() billingEmail?: string } class BillingInfoDto { @IsOptional() @IsString() @MaxLength(200) companyName?: string @IsOptional() @IsString() @MaxLength(40) vatId?: string @IsOptional() @IsString() @MaxLength(2) country?: string - @IsOptional() @IsEmail() contactEmail?: string + @EmptyToUndefined @IsOptional() @IsEmail() contactEmail?: string } export class UpdatePartnerDto {