import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsString, IsEnum, IsNotEmpty, MinLength, MaxLength, IsOptional, IsUrl, IsBoolean, ValidateNested, Matches, IsUUID, } from 'class-validator'; import { Type } from 'class-transformer'; import { OrganizationType } from '../../domain/entities/organization.entity'; /** * Address DTO */ export class AddressDto { @ApiProperty({ example: '123 Main Street', description: 'Street address', }) @IsString() @IsNotEmpty() street: string; @ApiProperty({ example: 'Rotterdam', description: 'City', }) @IsString() @IsNotEmpty() city: string; @ApiPropertyOptional({ example: 'South Holland', description: 'State or province', }) @IsString() @IsOptional() state?: string; @ApiProperty({ example: '3000 AB', description: 'Postal code', }) @IsString() @IsNotEmpty() postalCode: string; @ApiProperty({ example: 'NL', description: 'Country code (ISO 3166-1 alpha-2)', minLength: 2, maxLength: 2, }) @IsString() @MinLength(2) @MaxLength(2) @Matches(/^[A-Z]{2}$/, { message: 'Country must be a 2-letter ISO code (e.g., NL, US, CN)' }) country: string; } /** * Create Organization DTO */ export class CreateOrganizationDto { @ApiProperty({ example: 'Acme Freight Forwarding', description: 'Organization name', minLength: 2, maxLength: 200, }) @IsString() @IsNotEmpty() @MinLength(2) @MaxLength(200) name: string; @ApiProperty({ example: OrganizationType.FREIGHT_FORWARDER, description: 'Organization type', enum: OrganizationType, }) @IsEnum(OrganizationType) type: OrganizationType; @ApiPropertyOptional({ example: 'MAEU', description: 'Standard Carrier Alpha Code (4 uppercase letters, required for carriers only)', minLength: 4, maxLength: 4, }) @IsString() @IsOptional() @MinLength(4) @MaxLength(4) @Matches(/^[A-Z]{4}$/, { message: 'SCAC must be 4 uppercase letters (e.g., MAEU, MSCU)' }) scac?: string; @ApiProperty({ description: 'Organization address', type: AddressDto, }) @ValidateNested() @Type(() => AddressDto) address: AddressDto; @ApiPropertyOptional({ example: 'https://example.com/logo.png', description: 'Logo URL', }) @IsUrl() @IsOptional() logoUrl?: string; } /** * Update Organization DTO */ export class UpdateOrganizationDto { @ApiPropertyOptional({ example: 'Acme Freight Forwarding Inc.', description: 'Organization name', minLength: 2, maxLength: 200, }) @IsString() @IsOptional() @MinLength(2) @MaxLength(200) name?: string; @ApiPropertyOptional({ description: 'Organization address', type: AddressDto, }) @ValidateNested() @Type(() => AddressDto) @IsOptional() address?: AddressDto; @ApiPropertyOptional({ example: 'https://example.com/logo.png', description: 'Logo URL', }) @IsUrl() @IsOptional() logoUrl?: string; @ApiPropertyOptional({ example: true, description: 'Active status', }) @IsBoolean() @IsOptional() isActive?: boolean; } /** * Organization Document DTO */ export class OrganizationDocumentDto { @ApiProperty({ example: '550e8400-e29b-41d4-a716-446655440000', description: 'Document ID', }) @IsUUID() id: string; @ApiProperty({ example: 'business_license', description: 'Document type', }) @IsString() type: string; @ApiProperty({ example: 'Business License 2025', description: 'Document name', }) @IsString() name: string; @ApiProperty({ example: 'https://s3.amazonaws.com/xpeditis/documents/doc123.pdf', description: 'Document URL', }) @IsUrl() url: string; @ApiProperty({ example: '2025-01-15T10:00:00Z', description: 'Upload timestamp', }) uploadedAt: Date; } /** * Organization Response DTO */ export class OrganizationResponseDto { @ApiProperty({ example: '550e8400-e29b-41d4-a716-446655440000', description: 'Organization ID', }) id: string; @ApiProperty({ example: 'Acme Freight Forwarding', description: 'Organization name', }) name: string; @ApiProperty({ example: OrganizationType.FREIGHT_FORWARDER, description: 'Organization type', enum: OrganizationType, }) type: OrganizationType; @ApiPropertyOptional({ example: 'MAEU', description: 'Standard Carrier Alpha Code (carriers only)', }) scac?: string; @ApiProperty({ description: 'Organization address', type: AddressDto, }) address: AddressDto; @ApiPropertyOptional({ example: 'https://example.com/logo.png', description: 'Logo URL', }) logoUrl?: string; @ApiProperty({ description: 'Organization documents', type: [OrganizationDocumentDto], }) documents: OrganizationDocumentDto[]; @ApiProperty({ example: true, description: 'Active status', }) isActive: boolean; @ApiProperty({ example: '2025-01-01T00:00:00Z', description: 'Creation timestamp', }) createdAt: Date; @ApiProperty({ example: '2025-01-15T10:00:00Z', description: 'Last update timestamp', }) updatedAt: Date; } /** * Organization List Response DTO */ export class OrganizationListResponseDto { @ApiProperty({ description: 'List of organizations', type: [OrganizationResponseDto], }) organizations: OrganizationResponseDto[]; @ApiProperty({ example: 25, description: 'Total number of organizations', }) total: number; @ApiProperty({ example: 1, description: 'Current page number', }) page: number; @ApiProperty({ example: 20, description: 'Page size', }) pageSize: number; @ApiProperty({ example: 2, description: 'Total number of pages', }) totalPages: number; }