302 lines
5.7 KiB
TypeScript
302 lines
5.7 KiB
TypeScript
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;
|
|
}
|