import { Type } from 'class-transformer'; import { IsArray, IsBoolean, IsDateString, IsNumber, IsObject, IsOptional, IsString, MaxLength, Min, MinLength, ValidateIf, ValidateNested, } from 'class-validator'; export class CreatePipelineDto { @IsString() @MinLength(2) @MaxLength(120) name!: string; } export class DealLineItemInputDto { @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() productId?: string | null; @IsString() @MinLength(1) @MaxLength(200) name!: string; @Type(() => Number) @IsNumber() @Min(0.01) quantity!: number; @Type(() => Number) @IsNumber() @Min(0) unitPrice!: number; @IsOptional() @IsString() @MaxLength(8) currency?: string; } export class CreateDealDto { @IsString() @MinLength(2) @MaxLength(200) title!: string; @IsOptional() @IsString() pipelineId?: string; @IsOptional() @IsString() stageId?: string; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @Type(() => Number) @IsNumber() @Min(0) amount?: number | null; @IsOptional() @IsString() @MaxLength(8) currency?: string; @IsOptional() @IsString() @MaxLength(120) source?: string; @IsOptional() @IsString() @MaxLength(2000) notes?: string; @IsOptional() @IsArray() @IsString({ each: true }) tags?: string[]; @IsOptional() @IsBoolean() isStale?: boolean; @IsOptional() @IsBoolean() isRotten?: boolean; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsDateString() expectedCloseAt?: string | null; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() personId?: string | null; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() companyId?: string | null; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() ownerId?: string | null; @IsOptional() @IsObject() customFields?: Record; @IsOptional() @IsArray() @ValidateNested({ each: true }) @Type(() => DealLineItemInputDto) lineItems?: DealLineItemInputDto[]; } export class UpdateDealDto { @IsOptional() @IsString() @MinLength(2) @MaxLength(200) title?: string; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @Type(() => Number) @IsNumber() @Min(0) amount?: number | null; @IsOptional() @IsString() @MaxLength(8) currency?: string; @IsOptional() @IsString() @MaxLength(120) source?: string; @IsOptional() @IsString() @MaxLength(2000) notes?: string; @IsOptional() @IsArray() @IsString({ each: true }) tags?: string[]; @IsOptional() @IsBoolean() isStale?: boolean; @IsOptional() @IsBoolean() isRotten?: boolean; @IsOptional() @IsString() @MaxLength(400) lostReason?: string | null; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsDateString() expectedCloseAt?: string | null; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() personId?: string | null; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() companyId?: string | null; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() ownerId?: string | null; @IsOptional() @IsObject() customFields?: Record; @IsOptional() @IsArray() @ValidateNested({ each: true }) @Type(() => DealLineItemInputDto) lineItems?: DealLineItemInputDto[]; } export class MoveDealDto { @IsString() stageId!: string; @IsOptional() @Type(() => Number) @IsNumber() @Min(0) position?: number; }