mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 02:58:11 +00:00
160 lines
7.8 KiB
TypeScript
160 lines
7.8 KiB
TypeScript
import { IsString, IsDateString, IsInt, IsOptional, Min, IsEnum } from 'class-validator';
|
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
import { Type } from 'class-transformer';
|
|
import { Currency } from '@prisma/client';
|
|
|
|
export class SearchTripsDto {
|
|
@ApiProperty({ example: 'station-uuid', description: 'Origin station UUID — any intermediate stop is valid, not just the terminal' })
|
|
@IsString() originStationId: string;
|
|
|
|
@ApiProperty({ example: 'station-uuid', description: 'Destination station UUID — must appear after origin in the stop sequence' })
|
|
@IsString() destinationStationId: string;
|
|
|
|
@ApiProperty({ example: '2026-06-15', description: 'Departure date (YYYY-MM-DD)' })
|
|
@IsDateString() date: string;
|
|
|
|
@ApiProperty({ example: 2, description: 'Number of adult passengers (age ≥5 years) - pay 100% of base fare' })
|
|
@Type(() => Number) @IsInt() @Min(1) adultCount: number;
|
|
|
|
@ApiPropertyOptional({ example: 1, description: 'Number of child passengers (age <5 years). First child travels FREE, subsequent children pay 100%.' })
|
|
@IsOptional() @Type(() => Number) @IsInt() @Min(0) childCount?: number;
|
|
|
|
@ApiPropertyOptional({ example: 'Ethiopian', description: 'Passenger nationality: Ethiopian (Verifayda verification), Djiboutian (Waafi payment), Other (international payments)' })
|
|
@IsOptional() @IsString() nationality?: string;
|
|
|
|
@ApiPropertyOptional({ example: 'ONE_WAY', enum: ['ONE_WAY', 'ROUND_TRIP'], description: 'Journey type: ONE_WAY or ROUND_TRIP' })
|
|
@IsOptional() @IsEnum(['ONE_WAY', 'ROUND_TRIP']) journeyType?: string;
|
|
|
|
@ApiPropertyOptional({ example: '2026-06-20', description: 'Return date (YYYY-MM-DD) — required for ROUND_TRIP, must be after outbound date' })
|
|
@IsOptional() @IsDateString() returnDate?: string;
|
|
}
|
|
|
|
export class AvailableDatesQueryDto {
|
|
@ApiProperty({ example: 'station-uuid', description: 'Origin station UUID' })
|
|
@IsString() originStationId: string;
|
|
|
|
@ApiProperty({ example: 'station-uuid', description: 'Destination station UUID' })
|
|
@IsString() destinationStationId: string;
|
|
|
|
@ApiProperty({ example: '2026-06-15', description: 'Start of the date range (YYYY-MM-DD)' })
|
|
@IsDateString() from: string;
|
|
|
|
@ApiProperty({ example: '2026-09-13', description: 'End of the date range (YYYY-MM-DD), inclusive — server clamps to a max 90-day span' })
|
|
@IsDateString() to: string;
|
|
}
|
|
|
|
export class FareQuoteDto {
|
|
@ApiProperty({ example: 'schedule-uuid', description: 'TrainSchedule UUID from search results' })
|
|
@IsString() scheduleId: string;
|
|
|
|
@ApiProperty({ example: 'station-uuid', description: 'Origin station UUID (must be a stop on the schedule)' })
|
|
@IsString() originStationId: string;
|
|
|
|
@ApiProperty({ example: 'station-uuid', description: 'Destination station UUID (must come after origin in stop sequence)' })
|
|
@IsString() destinationStationId: string;
|
|
|
|
@ApiProperty({ example: 'Economy Regular', description: 'Seat class name: "Economy Regular" | "Economy Bed" | "VIP Bed"' })
|
|
@IsString() seatClassName: string;
|
|
|
|
@ApiProperty({ example: 2, description: 'Number of adult passengers (≥5 years) - each pays 100% of base fare' })
|
|
@Type(() => Number) @IsInt() @Min(1) adultCount: number;
|
|
|
|
@ApiPropertyOptional({ example: 1, description: 'Number of child passengers (<5 years) - first child FREE, subsequent children 100%' })
|
|
@IsOptional() @Type(() => Number) @IsInt() @Min(0) childCount?: number;
|
|
|
|
@ApiPropertyOptional({ example: 'WEEKEND15' })
|
|
@IsOptional() @IsString() promoCode?: string;
|
|
|
|
@ApiPropertyOptional({ example: 450, description: 'Loyalty points to redeem (10 points = 1 ETB minor unit)' })
|
|
@IsOptional() @Type(() => Number) @IsInt() loyaltyRedemptionPoints?: number;
|
|
|
|
@ApiPropertyOptional({ example: 'USD', enum: Currency, description: 'Display currency: ETB (default), DJF, USD. Transaction always in ETB.' })
|
|
@IsOptional() @IsEnum(Currency) displayCurrency?: Currency;
|
|
|
|
@ApiPropertyOptional({ example: 'Ethiopian', description: 'Passenger nationality for payment method filtering' })
|
|
@IsOptional() @IsString() nationality?: string;
|
|
|
|
@ApiPropertyOptional({ example: 'schedule-uuid', description: 'Return schedule UUID (required for ROUND_TRIP journeys)' })
|
|
@IsOptional() @IsString() returnScheduleId?: string;
|
|
|
|
@ApiPropertyOptional({ example: 'station-uuid', description: 'Return origin station ID (required for ROUND_TRIP)' })
|
|
@IsOptional() @IsString() returnOriginStationId?: string;
|
|
|
|
@ApiPropertyOptional({ example: 'station-uuid', description: 'Return destination station ID (required for ROUND_TRIP)' })
|
|
@IsOptional() @IsString() returnDestinationStationId?: string;
|
|
}
|
|
|
|
export class CoachTypeOptionClass {
|
|
@ApiProperty({ example: 'Economy Regular' }) name: string;
|
|
@ApiProperty({ example: 35000 }) baseFareMinor: number;
|
|
}
|
|
|
|
export class FareBreakdownPassengerDto {
|
|
@ApiProperty({ example: 'Abebe Kebede', description: 'Passenger name (for display only)' })
|
|
@IsString() passengerName: string;
|
|
|
|
@ApiProperty({ example: '1985-03-15', description: 'Date of birth — determines ADULT (≥5 yrs) or CHILD (<5 yrs)' })
|
|
@IsDateString() dateOfBirth: string;
|
|
|
|
@ApiProperty({ example: 'seat-class-uuid', description: 'SeatClass UUID for this passenger' })
|
|
@IsString() seatClassId: string;
|
|
|
|
@ApiPropertyOptional({ example: 'Ethiopian', description: 'Nationality — affects billing currency and seat class variant' })
|
|
@IsOptional() @IsString() nationality?: string;
|
|
}
|
|
|
|
export class FareBreakdownRequestDto {
|
|
@ApiProperty({ example: 'schedule-uuid' })
|
|
@IsString() scheduleId: string;
|
|
|
|
@ApiProperty({ example: 'station-uuid', description: 'Origin station UUID (must be a stop on the schedule)' })
|
|
@IsString() originStationId: string;
|
|
|
|
@ApiProperty({ example: 'station-uuid', description: 'Destination station UUID' })
|
|
@IsString() destinationStationId: string;
|
|
|
|
@ApiProperty({
|
|
example: '[{"passengerName":"Abebe","dateOfBirth":"1985-03-15","seatClassId":"uuid","nationality":"Ethiopian"}]',
|
|
description: 'URL-encoded JSON array of passengers. Each entry: { passengerName, dateOfBirth (YYYY-MM-DD), seatClassId, nationality? }',
|
|
})
|
|
@IsString() passengers: string;
|
|
|
|
@ApiPropertyOptional({ example: 'WEEKEND15' })
|
|
@IsOptional() @IsString() promoCode?: string;
|
|
|
|
@ApiPropertyOptional({ example: 'USD', enum: Currency })
|
|
@IsOptional() @IsEnum(Currency) displayCurrency?: Currency;
|
|
}
|
|
|
|
export class CoachTypeOption {
|
|
@ApiProperty({ example: 'coach-type-uuid' }) coachTypeId: string;
|
|
@ApiProperty({ example: 'Economy' }) coachTypeName: string;
|
|
@ApiProperty({ example: 'ECO' }) coachTypeCode: string;
|
|
@ApiProperty({ type: 'array', items: { type: 'object', $ref: '#/components/schemas/CoachTypeOptionClass' } }) classes: CoachTypeOptionClass[];
|
|
}
|
|
|
|
export class TransitLegDto {
|
|
@ApiProperty({ example: 'schedule-uuid' }) scheduleId: string;
|
|
@ApiProperty() trainNumber: string;
|
|
@ApiProperty() trainName: string;
|
|
@ApiProperty() origin: object;
|
|
@ApiProperty() destination: object;
|
|
@ApiProperty() departureAt: Date;
|
|
@ApiProperty() arrivalAt: Date;
|
|
@ApiProperty() durationMinutes: number;
|
|
@ApiProperty() availabilityByClass: object;
|
|
@ApiProperty() faresByClass: object[];
|
|
@ApiProperty() coachTypes: CoachTypeOption[];
|
|
}
|
|
|
|
export class TransitResultDto {
|
|
@ApiProperty({ example: 'TRANSIT' }) type: string;
|
|
@ApiProperty({ example: 'station-uuid' }) transitStationId: string;
|
|
@ApiProperty({ example: 'Dire Dawa' }) transitStationName: string;
|
|
@ApiProperty({ description: 'Connection wait time in minutes' }) connectionMinutes: number;
|
|
@ApiProperty({ type: TransitLegDto }) leg1: TransitLegDto;
|
|
@ApiProperty({ type: TransitLegDto }) leg2: TransitLegDto;
|
|
@ApiProperty({ description: 'Combined minimum fare across all shared classes', example: 70000 }) combinedMinFareMinor: number;
|
|
@ApiProperty({ description: 'Total travel time including connection in minutes' }) totalDurationMinutes: number;
|
|
}
|