import { IsString, IsOptional, IsEmail, MaxLength, IsEnum, IsIn, Matches, } from 'class-validator'; import { ETHIOPIAN_REGIONS, type EthiopianRegion } from '@edr/types'; import { CompanyNationality } from '../entities/company.entity'; import { IsValidPhone } from '../../../common/validators/is-phone-number.validator'; import { IsTin } from '../../../common/validators/is-tin.validator'; export class UpdateProfileDto { @IsOptional() @IsEnum(CompanyNationality) nationality?: CompanyNationality; @IsOptional() @IsString() @MaxLength(200) companyName?: string; @IsOptional() @IsEmail() @MaxLength(150) companyEmail?: string; @IsOptional() @IsString() @MaxLength(20) @IsValidPhone() companyPhone?: string; @IsOptional() @IsString() @MaxLength(32) companyLocation?: string; @IsOptional() @IsString() companyAddress?: string; @IsOptional() @IsString() @IsTin({ message: 'TIN must be exactly 10 digits' }) tin?: string; // Ethiopian VAT registration numbers are 10 digits, the same shape as the // TIN. Both portal forms enforce that; without it here the API happily stored // whatever a stale client sent, and the two layers disagreed about what the // column may hold. @IsOptional() @IsString() @Matches(/^\d{10}$/, { message: 'VAT number must be exactly 10 digits' }) vatNumber?: string; // `fanNumber` is deliberately absent: the FAN is the Fayda number of the // company's PoA (or its general manager), so it is derived from a completed // Fayda verification rather than typed. The global validation pipe runs with // forbidNonWhitelisted, so a client that still sends it gets a 400 telling it // so — see CompaniesService.completeIdentityVerification. @IsOptional() @IsString() contactPersonName?: string; @IsOptional() @IsString() contactPersonPosition?: string; @IsOptional() @IsEmail() contactPersonEmail?: string; @IsOptional() @IsString() @IsValidPhone() contactPersonPhone?: string; /** * The contact-person phone that completed SMS OTP verification. Persisted so * the onboarding "verify" step can resume its "done" state after a refresh * (compared against the current contactPersonPhone on the client). */ @IsOptional() @IsString() @IsValidPhone() contactVerifiedPhone?: string; @IsOptional() @IsString() generalManagerName?: string; @IsOptional() @IsEmail() generalManagerEmail?: string; @IsOptional() @IsString() @IsValidPhone() generalManagerPhone?: string; @IsOptional() @IsString() poaName?: string; @IsOptional() @IsString() @IsValidPhone() poaPhone?: string; @IsOptional() @IsEmail() poaEmail?: string; @IsOptional() @IsString() poaLocation?: string; @IsOptional() @IsString() poaAddress?: string; /** * The owner's passport number — the identity credential for a foreign * company, since Fayda is an Ethiopian national ID. Plain typed field, never * written or locked by a Fayda verification: still required even if the * owner also verifies. */ @IsOptional() @IsString() ownerPassportNumber?: string; @IsOptional() @IsString() @MaxLength(100) licenceNumber?: string; @IsOptional() @IsString() statusDescription?: string; @IsOptional() @IsString() @MaxLength(50) dateRegistered?: string; @IsOptional() @IsString() @MaxLength(50) renewedFrom?: string; @IsOptional() @IsString() @MaxLength(50) renewalDate?: string; @IsOptional() @IsString() @MaxLength(50) renewedTo?: string; // Zone/woreda/kebele below stay free text: there is no authoritative dataset // of Ethiopian zones/woredas/kebeles in the platform yet, and eTrade returns // them uncoded. Only region is a closed set today. @IsOptional() @IsIn(ETHIOPIAN_REGIONS as unknown as string[], { message: "region must be a recognised Ethiopian region", }) region?: EthiopianRegion; @IsOptional() @IsString() @MaxLength(100) zone?: string; @IsOptional() @IsString() @MaxLength(100) woreda?: string; @IsOptional() @IsString() @MaxLength(100) kebele?: string; @IsOptional() @IsString() @MaxLength(100) houseNo?: string; // Not validated as a phone number: eTrade-sourced, so a fresh eTrade lookup // overwrites whatever the client sends here — see // CompaniesService.applyEtradeSourcedFields. Presence just flags "this save // touches an eTrade-owned field." @IsOptional() @IsString() @MaxLength(20) etradePhone?: string; }