import { IsString, IsInt, IsOptional, IsArray, IsBoolean } from 'class-validator'; import { ApiProperty, ApiPropertyOptional, PartialType, OmitType } from '@nestjs/swagger'; export class CreateTrainDto { @ApiProperty({ example: '301', description: 'Unique train service number' }) @IsString() number: string; @ApiProperty({ example: 'Express 301' }) @IsString() name: string; @ApiPropertyOptional({ example: 'EDR', description: 'Operator ID (defaults to op_edr)' }) @IsOptional() @IsString() operatorId?: string; @ApiPropertyOptional({ example: 'Ethiopian-Djibouti Railway' }) @IsOptional() @IsString() operatorName?: string; @ApiPropertyOptional({ example: 'Addis-Djibouti Express' }) @IsOptional() @IsString() description?: string; @ApiPropertyOptional({ example: true, description: 'Whether the train is active' }) @IsOptional() @IsBoolean() isActive?: boolean; } export class CreateCoachDto { @ApiProperty({ example: 'A-001', description: 'Unique coach number' }) @IsString() number: string; @ApiProperty({ example: 'coach-type-uuid', description: 'Coach Type UUID' }) @IsString() coachTypeId: string; @ApiProperty({ example: '2+2', description: 'Seat arrangement for regular coaches (e.g., "2+2", "3+2"). Ignored for bed coaches.' }) @IsString() arrangement: string; @ApiProperty({ example: 60, description: 'Total seat/bed capacity' }) @IsInt() capacity: number; @ApiPropertyOptional({ example: 'ACTIVE', description: 'Status: ACTIVE, INACTIVE' }) @IsOptional() @IsString() status?: string; @ApiPropertyOptional({ enum: ['ECONOMY_BED', 'VIP_BED'], description: 'Bed coach category. Set to generate bed/sleeper compartments instead of regular seats. Overrides name-based detection.', example: 'VIP_BED', }) @IsOptional() @IsString() bedCategory?: 'ECONOMY_BED' | 'VIP_BED'; @ApiPropertyOptional({ example: 4, description: 'Beds per compartment/room. Must be even (split equally left/right). Defaults: VIP_BED=4, ECONOMY_BED=6. Only applies when bedCategory is set.', }) @IsOptional() @IsInt() bedsPerRoom?: number; @ApiPropertyOptional({ example: 1, description: 'Sequence number for ordering coaches in the train' }) @IsOptional() @IsInt() sequence?: number; } export class UpdateCoachDto extends PartialType(OmitType(CreateCoachDto, ['number'] as const)) { @ApiPropertyOptional({ example: 1, description: 'Sequence number for ordering' }) @IsOptional() @IsInt() sequence?: number; } export class AssignCoachDto { @ApiProperty({ example: 'schedule-uuid', description: 'TrainSchedule UUID' }) @IsString() scheduleId: string; @ApiProperty({ example: 'coach-uuid', description: 'Coach UUID' }) @IsString() coachId: string; @ApiProperty({ example: 1, description: 'Position in the train consist' }) @IsInt() positionNumber: number; @ApiPropertyOptional({ example: true, description: 'Whether this coach is operational' }) @IsOptional() @IsBoolean() isOperational?: boolean; } export class ListCoachesDto { @ApiPropertyOptional({ example: 'ACTIVE', description: 'Filter by status: ACTIVE, INACTIVE' }) @IsOptional() @IsString() status?: string; @ApiPropertyOptional({ example: 'schedule-uuid', description: 'Filter coaches assigned to this schedule' }) @IsOptional() @IsString() scheduleId?: string; } // Legacy DTO types for backward compatibility export class CreateCoachTypeDto { @ApiProperty({ example: 'sleeper' }) @IsString() code: string; @ApiProperty({ example: 'Sleeper Coach' }) @IsString() name: string; @IsOptional() @IsString() type?: string; } export class UpdateCoachTypeDto { @ApiPropertyOptional({ example: 'sleeper' }) @IsOptional() @IsString() code?: string; @ApiPropertyOptional({ example: 'Sleeper Coach' }) @IsOptional() @IsString() name?: string; @ApiPropertyOptional({ example: 'sleeper' }) @IsOptional() @IsString() type?: string; } export class CreateClassDto { @ApiProperty({ example: 'coach-type-uuid' }) @IsString() coachTypeId: string; @ApiProperty({ example: 'Economy' }) @IsString() name: string; @IsOptional() @IsString() description?: string; @ApiProperty({ example: 5000 }) @IsInt() baseFareMinor: number; @ApiPropertyOptional({ example: 0 }) @IsOptional() @IsInt() premiumMinor?: number; @ApiPropertyOptional({ example: 0 }) @IsOptional() @IsInt() insuranceFeeMinor?: number; @ApiPropertyOptional({ example: true }) @IsOptional() @IsBoolean() isActive?: boolean; } export class UpdateClassDto { @ApiPropertyOptional({ example: 'coach-type-uuid' }) @IsOptional() @IsString() coachTypeId?: string; @ApiPropertyOptional({ example: 'Economy' }) @IsOptional() @IsString() name?: string; @ApiPropertyOptional() @IsOptional() @IsString() description?: string; @ApiPropertyOptional({ example: 5000 }) @IsOptional() @IsInt() baseFareMinor?: number; @ApiPropertyOptional({ example: true }) @IsOptional() @IsBoolean() isActive?: boolean; } export class GenerateSeatMapDto { @ApiProperty({ example: 2, description: 'Number of coaches' }) @IsInt() coachCount: number; @ApiProperty({ example: 9, description: 'Number of rooms (compartments) per coach' }) @IsInt() roomsPerCoach: number; @ApiProperty({ enum: ['ECONOMY_BED', 'VIP_BED'], example: 'ECONOMY_BED', description: 'ECONOMY_BED = 6 beds/room (L/M/U × Left/Right), VIP_BED = 4 beds/room (L/U × Left/Right)' }) @IsString() roomType: 'ECONOMY_BED' | 'VIP_BED'; }