import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Transform } from 'class-transformer'; import { IsArray, IsEnum, IsNumber, IsOptional, IsString, IsUUID, Min, } from 'class-validator'; export interface CargoContainerLine { containerSize: string; quantity: number; } /** * Cargo-aware availability query. Beyond the route yards, it carries the cargo * sizing so the service can check matching-wagon + train capacity per day. The * `containers` array is passed as a JSON string in the query string (GET) and * parsed here. */ export class AvailableDaysForCargoQueryDto { @ApiPropertyOptional({ format: 'uuid' }) @IsOptional() @IsUUID() originYardId?: string; @ApiPropertyOptional({ format: 'uuid' }) @IsOptional() @IsUUID() destinationYardId?: string; @ApiProperty({ enum: ['CONTAINER', 'BULK'] }) @IsEnum(['CONTAINER', 'BULK']) freightType!: 'CONTAINER' | 'BULK'; @ApiPropertyOptional({ description: 'Bulk cargo type code (e.g. COFFEE).' }) @IsOptional() @IsString() cargoTypeCode?: string; @ApiPropertyOptional({ format: 'uuid', description: 'Bulk cargo type id (preferred over code).' }) @IsOptional() @IsUUID() cargoTypeId?: string; @ApiPropertyOptional({ description: 'Container type ids as a JSON string array — enables the exact wagon-type compatibility gate (falls back to containerSize matching when absent).', }) @IsOptional() @Transform(({ value }) => { if (value == null || value === '') return undefined; if (typeof value !== 'string') return value; try { return JSON.parse(value); } catch { return undefined; } }) @IsArray() containerTypeIds?: string[]; @ApiPropertyOptional({ description: 'Total bulk weight in tons.' }) @IsOptional() @Transform(({ value }) => (value === '' || value == null ? undefined : Number(value))) @IsNumber() @Min(0) totalWeightTons?: number; @ApiPropertyOptional({ description: 'Container lines as a JSON string: [{containerSize,quantity}].', }) @IsOptional() @Transform(({ value }) => { if (value == null || value === '') return undefined; if (typeof value !== 'string') return value; try { return JSON.parse(value); } catch { return undefined; } }) @IsArray() containers?: CargoContainerLine[]; }