import { Type } from 'class-transformer'; import { ArrayMaxSize, ArrayMinSize, IsArray, IsBoolean, IsEmail, IsIn, IsInt, IsObject, IsOptional, IsString, Max, MaxLength, Min, MinLength, ValidateIf, } from 'class-validator'; import { PERSON_GENDERS, PERSON_IMPORT_SOURCES, PERSON_MOODS } from '@mento/shared'; export class BirthdaySmsDto { @IsString() @MinLength(1) @MaxLength(500) text!: string; } export class BulkDeletePeopleDto { @IsArray() @ArrayMinSize(1) @ArrayMaxSize(500) @IsString({ each: true }) ids!: string[]; } export class ListQueryDto { @IsOptional() @IsString() q?: string; @IsOptional() @Type(() => Number) @IsInt() @Min(1) page?: number = 1; @IsOptional() @Type(() => Number) @IsInt() @Min(1) @Max(100) limit?: number = 20; /** وضعیت مشتری؛ چندتایی با کاما */ @IsOptional() @IsString() @MaxLength(120) mood?: string; @IsOptional() @IsIn(['name', 'newest']) sort?: 'name' | 'newest'; /** فیلتر منبع ورود شخص؛ چندتایی با کاما */ @IsOptional() @IsString() @MaxLength(400) importSource?: string; /** استان شرکت مرتبط */ @IsOptional() @IsString() @MaxLength(80) province?: string; /** شهر/شهرستان شرکت مرتبط */ @IsOptional() @IsString() @MaxLength(80) city?: string; /** فقط کسانی که موبایل دارند */ @IsOptional() @IsIn(['1', 'true', '0', 'false']) hasMobile?: string; /** فیلتر تیپ DISC غالب یا ترکیبی، مثل D یا D/C */ @IsOptional() @IsString() @MaxLength(12) disc?: string; /** فیلتر گروه مشتری؛ چندتایی با کاما (هر کدام از گروه‌ها) */ @IsOptional() @IsString() @MaxLength(2000) groupId?: string; } class CompanyExtraFieldsDto { @IsOptional() @IsString() @MaxLength(60) code?: string | null; @IsOptional() @IsString() @MaxLength(40) importSource?: string; @IsOptional() @IsString() @MaxLength(80) sourceRef?: string | null; @IsOptional() @IsString() @MaxLength(40) economicCode?: string | null; @IsOptional() @IsString() @MaxLength(40) registrationNumber?: string | null; @IsOptional() @IsString() @MaxLength(400) otherPhones?: string | null; @IsOptional() @IsString() @MaxLength(40) fax?: string | null; @IsOptional() @IsString() @MaxLength(400) otherEmails?: string | null; @IsOptional() @IsString() @MaxLength(80) province?: string | null; @IsOptional() @IsString() @MaxLength(80) city?: string | null; @IsOptional() @IsString() @MaxLength(20) postalCode?: string | null; @IsOptional() @IsString() @MaxLength(120) groupName?: string | null; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() registeredAt?: string | null; @IsOptional() @IsArray() @IsString({ each: true }) groupIds?: string[]; } export class CreateCompanyDto extends CompanyExtraFieldsDto { @IsString() @MinLength(2) @MaxLength(160) name!: string; @IsOptional() @IsString() @MaxLength(32) nationalId?: string; @IsOptional() @IsString() @MaxLength(40) phone?: string; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsEmail() email?: string; @IsOptional() @IsString() @MaxLength(200) website?: string; @IsOptional() @IsString() @MaxLength(400) address?: string; @IsOptional() @IsString() @MaxLength(2000) notes?: string; @IsOptional() @IsArray() @IsString({ each: true }) tags?: string[]; @IsOptional() @IsObject() customFields?: Record; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() ownerId?: string | null; } export class UpdateCompanyDto extends CompanyExtraFieldsDto { @IsOptional() @IsString() @MinLength(2) @MaxLength(160) name?: string; @IsOptional() @IsString() @MaxLength(32) nationalId?: string; @IsOptional() @IsString() @MaxLength(40) phone?: string; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsEmail() email?: string; @IsOptional() @IsString() @MaxLength(200) website?: string; @IsOptional() @IsString() @MaxLength(400) address?: string; @IsOptional() @IsString() @MaxLength(2000) notes?: string; @IsOptional() @IsArray() @IsString({ each: true }) tags?: string[]; @IsOptional() @IsObject() customFields?: Record; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() ownerId?: string | null; } export class CreatePersonDto { @IsOptional() @IsString() @MaxLength(80) firstName?: string; @IsOptional() @IsString() @MaxLength(80) lastName?: string; @IsOptional() @IsIn(PERSON_GENDERS) gender?: (typeof PERSON_GENDERS)[number]; @IsOptional() @IsBoolean() showGenderInName?: boolean; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() @MaxLength(80) previousFirstName?: string | null; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() @MaxLength(80) previousLastName?: string | null; @IsOptional() @IsString() @MaxLength(40) @IsIn([...PERSON_IMPORT_SOURCES]) importSource?: (typeof PERSON_IMPORT_SOURCES)[number]; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() @MaxLength(120) sourceRef?: string | null; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsEmail() email?: string; @IsOptional() @IsString() @MaxLength(40) phone?: string; @IsOptional() @IsString() @MaxLength(40) mobile?: string; @IsOptional() @IsString() @MaxLength(120) position?: string; @IsOptional() @IsString() @MaxLength(300) website?: string; @IsOptional() @IsString() @MaxLength(200) instagram?: string; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() birthDate?: string | null; @IsOptional() @IsString() @MaxLength(120) referrer?: string; @IsOptional() @IsArray() @IsString({ each: true }) addresses?: string[]; @IsOptional() @IsString() @MaxLength(2000) notes?: string; @IsOptional() @IsIn([...PERSON_MOODS]) mood?: (typeof PERSON_MOODS)[number]; @IsOptional() @IsArray() @IsString({ each: true }) tags?: string[]; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() companyId?: string | null; @IsOptional() @IsObject() customFields?: Record; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() ownerId?: string | null; /** فقط برای ایمپورت اکسل — تاریخ ثبت مبدأ */ @IsOptional() @IsString() registeredAt?: string | null; @IsOptional() @IsArray() @IsString({ each: true }) groupIds?: string[]; } export class UpdatePersonDto { @IsOptional() @IsString() @MaxLength(80) firstName?: string; @IsOptional() @IsString() @MaxLength(80) lastName?: string; @IsOptional() @IsIn(PERSON_GENDERS) gender?: (typeof PERSON_GENDERS)[number]; @IsOptional() @IsBoolean() showGenderInName?: boolean; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() @MaxLength(80) previousFirstName?: string | null; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() @MaxLength(80) previousLastName?: string | null; @IsOptional() @IsString() @MaxLength(40) importSource?: string; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() @MaxLength(120) sourceRef?: string | null; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsEmail() email?: string; @IsOptional() @IsString() @MaxLength(40) phone?: string; @IsOptional() @IsString() @MaxLength(40) mobile?: string; @IsOptional() @IsString() @MaxLength(120) position?: string; @IsOptional() @IsString() @MaxLength(300) website?: string; @IsOptional() @IsString() @MaxLength(200) instagram?: string; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() birthDate?: string | null; @IsOptional() @IsString() @MaxLength(120) referrer?: string; @IsOptional() @IsArray() @IsString({ each: true }) addresses?: string[]; @IsOptional() @IsString() @MaxLength(2000) notes?: string; @IsOptional() @IsIn([...PERSON_MOODS]) mood?: (typeof PERSON_MOODS)[number]; @IsOptional() @IsArray() @IsString({ each: true }) tags?: string[]; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() companyId?: string | null; @IsOptional() @IsObject() customFields?: Record; @IsOptional() @ValidateIf((_, v) => v !== '' && v != null) @IsString() ownerId?: string | null; @IsOptional() @IsArray() @IsString({ each: true }) groupIds?: string[]; }