import { IsEmail, IsString, MinLength, IsOptional, ValidateNested, IsEnum, MaxLength, Matches } from 'class-validator'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Type } from 'class-transformer'; import { OrganizationType } from '@domain/entities/organization.entity'; export class LoginDto { @ApiProperty({ example: 'john.doe@acme.com', description: 'Email address', }) @IsEmail({}, { message: 'Invalid email format' }) email: string; @ApiProperty({ example: 'SecurePassword123!', description: 'Password (minimum 12 characters)', minLength: 12, }) @IsString() @MinLength(12, { message: 'Password must be at least 12 characters' }) password: string; } /** * Organization data for registration (nested in RegisterDto) */ export class RegisterOrganizationDto { @ApiProperty({ example: 'Acme Freight Forwarding', description: 'Organization name', minLength: 2, maxLength: 200, }) @IsString() @MinLength(2) @MaxLength(200) name: string; @ApiProperty({ example: OrganizationType.FREIGHT_FORWARDER, description: 'Organization type', enum: OrganizationType, }) @IsEnum(OrganizationType) type: OrganizationType; @ApiProperty({ example: '123 Main Street', description: 'Street address', }) @IsString() street: string; @ApiProperty({ example: 'Rotterdam', description: 'City', }) @IsString() city: string; @ApiPropertyOptional({ example: 'South Holland', description: 'State or province', }) @IsString() @IsOptional() state?: string; @ApiProperty({ example: '3000 AB', description: 'Postal code', }) @IsString() 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; @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' }) scac?: string; } export class RegisterDto { @ApiProperty({ example: 'john.doe@acme.com', description: 'Email address', }) @IsEmail({}, { message: 'Invalid email format' }) email: string; @ApiProperty({ example: 'SecurePassword123!', description: 'Password (minimum 12 characters)', minLength: 12, }) @IsString() @MinLength(12, { message: 'Password must be at least 12 characters' }) password: string; @ApiPropertyOptional({ example: 'John', description: 'First name (optional if using invitation token)', }) @IsString() @IsOptional() @MinLength(2, { message: 'First name must be at least 2 characters' }) firstName: string; @ApiPropertyOptional({ example: 'Doe', description: 'Last name (optional if using invitation token)', }) @IsString() @IsOptional() @MinLength(2, { message: 'Last name must be at least 2 characters' }) lastName: string; @ApiPropertyOptional({ example: 'abc123def456', description: 'Invitation token (for invited users)', required: false, }) @IsString() @IsOptional() invitationToken?: string; @ApiPropertyOptional({ example: '550e8400-e29b-41d4-a716-446655440000', description: 'Organization ID (optional - for invited users). If not provided, organization data must be provided.', required: false, }) @IsString() @IsOptional() organizationId?: string; @ApiPropertyOptional({ description: 'Organization data (required if organizationId and invitationToken are not provided)', type: RegisterOrganizationDto, required: false, }) @ValidateNested() @Type(() => RegisterOrganizationDto) @IsOptional() organization?: RegisterOrganizationDto; } export class AuthResponseDto { @ApiProperty({ example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', description: 'JWT access token (valid 15 minutes)', }) accessToken: string; @ApiProperty({ example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', description: 'JWT refresh token (valid 7 days)', }) refreshToken: string; @ApiProperty({ example: { id: '550e8400-e29b-41d4-a716-446655440000', email: 'john.doe@acme.com', firstName: 'John', lastName: 'Doe', role: 'user', organizationId: '550e8400-e29b-41d4-a716-446655440001', }, description: 'User information', }) user: { id: string; email: string; firstName: string; lastName: string; role: string; organizationId: string; }; } export class RefreshTokenDto { @ApiProperty({ example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', description: 'Refresh token', }) @IsString() refreshToken: string; }