mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 12:41:04 +00:00
132 lines
8.3 KiB
TypeScript
132 lines
8.3 KiB
TypeScript
import { IsString, IsDateString, IsInt, IsOptional, IsEnum, IsArray, ValidateNested, IsObject, Min } from 'class-validator';
|
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
import { Type } from 'class-transformer';
|
|
|
|
export enum TripStatus {
|
|
SCHEDULED = 'SCHEDULED',
|
|
BOARDING = 'BOARDING',
|
|
EN_ROUTE = 'EN_ROUTE',
|
|
ARRIVED = 'ARRIVED',
|
|
CANCELLED = 'CANCELLED',
|
|
DELAYED = 'DELAYED',
|
|
}
|
|
|
|
export enum StopStatus {
|
|
COMPLETED = 'COMPLETED',
|
|
APPROACHING = 'APPROACHING',
|
|
CURRENT = 'CURRENT',
|
|
UPCOMING = 'UPCOMING',
|
|
}
|
|
|
|
export enum PassengerCategory {
|
|
ADULT = 'ADULT',
|
|
CHILD = 'CHILD',
|
|
}
|
|
|
|
export class PlannedStopTimeDto {
|
|
@ApiProperty({ example: 1, description: 'Route stop sequence number this timing applies to' }) @IsInt() @Min(1) sequence: number;
|
|
@ApiPropertyOptional({ example: '2026-06-15T09:30:00Z', description: 'Planned arrival at this stop (omit for first stop)' }) @IsOptional() @IsDateString() plannedArrivalAt?: string;
|
|
@ApiPropertyOptional({ example: '2026-06-15T09:45:00Z', description: 'Planned departure from this stop (omit for last stop)' }) @IsOptional() @IsDateString() plannedDepartureAt?: string;
|
|
}
|
|
|
|
export class CreateScheduleDto {
|
|
@ApiProperty({ example: 'train-uuid', description: 'Train UUID' }) @IsString() trainId: string;
|
|
|
|
@ApiProperty({ example: 'route-uuid', description: 'Route UUID — stops are copied from the route template. Origin and destination are derived from the first and last route stop.' })
|
|
@IsString() routeId: string;
|
|
|
|
@ApiProperty({ example: '2026-06-15T08:00:00Z', description: 'Scheduled departure from the first stop (origin)' }) @IsDateString() departureAt: string;
|
|
@ApiProperty({ example: '2026-06-15T20:00:00Z', description: 'Scheduled arrival at the last stop (destination)' }) @IsDateString() arrivalAt: string;
|
|
|
|
@ApiProperty({
|
|
type: [PlannedStopTimeDto],
|
|
description: 'Planned arrival/departure times per stop sequence. Must cover all stops defined on the route.',
|
|
example: [
|
|
{ sequence: 1, plannedDepartureAt: '2026-06-15T08:00:00Z' },
|
|
{ sequence: 2, plannedArrivalAt: '2026-06-15T09:30:00Z', plannedDepartureAt: '2026-06-15T09:45:00Z' },
|
|
{ sequence: 3, plannedArrivalAt: '2026-06-15T11:30:00Z', plannedDepartureAt: '2026-06-15T11:45:00Z' },
|
|
{ sequence: 4, plannedArrivalAt: '2026-06-15T15:00:00Z', plannedDepartureAt: '2026-06-15T15:20:00Z' },
|
|
{ sequence: 5, plannedArrivalAt: '2026-06-15T18:00:00Z', plannedDepartureAt: '2026-06-15T18:10:00Z' },
|
|
{ sequence: 6, plannedArrivalAt: '2026-06-15T20:00:00Z' },
|
|
],
|
|
})
|
|
@IsArray() @ValidateNested({ each: true }) @Type(() => PlannedStopTimeDto)
|
|
plannedTimes: PlannedStopTimeDto[];
|
|
}
|
|
|
|
export class UpdateScheduleDto {
|
|
@ApiPropertyOptional({ example: '2026-06-15T08:00:00Z', description: 'Scheduled departure from the first stop (origin)' }) @IsOptional() @IsDateString() departureAt?: string;
|
|
@ApiPropertyOptional({ example: '2026-06-15T20:00:00Z', description: 'Scheduled arrival at the last stop (destination)' }) @IsOptional() @IsDateString() arrivalAt?: string;
|
|
@ApiPropertyOptional({ enum: TripStatus, example: TripStatus.SCHEDULED }) @IsOptional() @IsEnum(TripStatus) status?: TripStatus;
|
|
@ApiPropertyOptional({ type: Array, description: 'List of coaches to assign' }) @IsOptional() @IsArray() coaches?: Array<{ coachId: string; positionNumber: number }>;
|
|
}
|
|
|
|
export class UpdateStopTimeDto {
|
|
@ApiPropertyOptional({ example: '2026-06-15T09:30:00Z' }) @IsOptional() @IsDateString() plannedArrivalAt?: string;
|
|
@ApiPropertyOptional({ example: '2026-06-15T09:45:00Z' }) @IsOptional() @IsDateString() plannedDepartureAt?: string;
|
|
@ApiPropertyOptional({ enum: StopStatus, example: StopStatus.UPCOMING }) @IsOptional() @IsEnum(StopStatus) status?: StopStatus;
|
|
}
|
|
|
|
export class CreateFareRuleDto {
|
|
@ApiPropertyOptional({ example: 'schedule-uuid', description: 'Scope fare rule to a specific schedule' }) @IsOptional() @IsString() scheduleId?: string;
|
|
@ApiPropertyOptional({ example: 'ADD-DJI', description: 'Scope fare rule to a route code (e.g. ADD-DJI for full route or ADD-ADM for segment)' }) @IsOptional() @IsString() route?: string;
|
|
@ApiPropertyOptional({ example: 'Ethiopian', description: 'Scope fare rule to nationality: Ethiopian, Djiboutian, Other' }) @IsOptional() @IsString() nationality?: string;
|
|
@ApiPropertyOptional({ enum: PassengerCategory, example: 'ADULT', description: 'Passenger category: ADULT (5+ yrs) or CHILD (<5 yrs)' }) @IsOptional() @IsEnum(PassengerCategory) passengerCategory?: PassengerCategory;
|
|
@ApiProperty({ example: 'seat-class-uuid', description: 'Seat class UUID' }) @IsString() seatClassId: string;
|
|
@ApiProperty({ example: 45000, description: 'Base fare in minor currency units (ETB cents)' }) @IsInt() baseFareMinor: number;
|
|
@ApiProperty({ example: '2026-01-01T00:00:00Z' }) @IsDateString() validFrom: string;
|
|
@ApiPropertyOptional({ example: '2026-12-31T23:59:59Z' }) @IsOptional() @IsDateString() validUntil?: string;
|
|
}
|
|
|
|
export class CreateSegmentFareRuleDto {
|
|
@ApiProperty({ example: 'route-uuid', description: 'Route UUID' }) @IsString() routeId: string;
|
|
@ApiProperty({ example: 1, description: 'Origin stop sequence number' }) @IsInt() @Min(1) originStopSequence: number;
|
|
@ApiProperty({ example: 2, description: 'Destination stop sequence number' }) @IsInt() @Min(1) destinationStopSequence: number;
|
|
@ApiProperty({ example: 'seat-class-uuid', description: 'Seat class UUID' }) @IsString() seatClassId: string;
|
|
@ApiProperty({ example: 45000, description: 'Base fare in minor currency units (ETB cents)' }) @IsInt() baseFareMinor: number;
|
|
@ApiPropertyOptional({ example: 'Ethiopian', description: 'Nationality scope (Ethiopian, Djiboutian, Other)' }) @IsOptional() @IsString() nationality?: string;
|
|
@ApiPropertyOptional({ enum: PassengerCategory, example: 'ADULT', description: 'Passenger category: ADULT (5+ yrs) or CHILD (<5 yrs)' }) @IsOptional() @IsEnum(PassengerCategory) passengerCategory?: PassengerCategory;
|
|
@ApiProperty({ example: '2026-01-01T00:00:00Z' }) @IsDateString() validFrom: string;
|
|
@ApiPropertyOptional({ example: '2026-12-31T23:59:59Z' }) @IsOptional() @IsDateString() validUntil?: string;
|
|
}
|
|
|
|
export class ListSchedulesDto {
|
|
@ApiPropertyOptional({ example: '2026-06-15', description: 'Filter by departure date (YYYY-MM-DD). Returns all schedules departing on this calendar day.' })
|
|
@IsOptional() @IsDateString() date?: string;
|
|
|
|
@ApiPropertyOptional({ example: 'route-uuid', description: 'Filter by route UUID' })
|
|
@IsOptional() @IsString() routeId?: string;
|
|
|
|
@ApiPropertyOptional({ example: 'train-uuid', description: 'Filter by train UUID' })
|
|
@IsOptional() @IsString() trainId?: string;
|
|
|
|
@ApiPropertyOptional({ enum: TripStatus, example: TripStatus.SCHEDULED, description: 'Filter by schedule status' })
|
|
@IsOptional() @IsEnum(TripStatus) status?: TripStatus;
|
|
}
|
|
|
|
export class UpdateScheduleStatusDto {
|
|
@ApiProperty({ enum: TripStatus, example: TripStatus.EN_ROUTE }) @IsEnum(TripStatus) status: TripStatus;
|
|
}
|
|
|
|
export class BulkCreateSchedulesDto {
|
|
@ApiProperty({ example: 'train-uuid', description: 'Train UUID' }) @IsString() trainId: string;
|
|
@ApiProperty({ example: 'route-uuid', description: 'Route UUID' }) @IsString() routeId: string;
|
|
@ApiProperty({ example: '2026-06-15T08:00:00Z', description: 'Start date and time for first schedule' }) @IsDateString() startDateTime: string;
|
|
@ApiProperty({ example: 12, description: 'Hours duration per schedule' }) @IsInt() @Min(1) durationHours: number;
|
|
@ApiProperty({ example: 2, description: 'Repeat every X days' }) @IsInt() @Min(1) repeatEveryDays: number;
|
|
@ApiProperty({ example: 30, description: 'Generate schedules for the next Y days' }) @IsInt() @Min(1) forNextDays: number;
|
|
@ApiPropertyOptional({ type: [PlannedStopTimeDto], description: 'Optional custom planned times per stop. If not provided, will auto-generate.' })
|
|
@IsOptional() @IsArray() @ValidateNested({ each: true }) @Type(() => PlannedStopTimeDto)
|
|
plannedTimes?: PlannedStopTimeDto[];
|
|
|
|
@ApiPropertyOptional({ type: [String], description: 'Optional coach UUIDs to assign to every generated schedule. Overrides the route coach template if provided.' })
|
|
@IsOptional() @IsArray() @IsString({ each: true })
|
|
coachIds?: string[];
|
|
}
|
|
|
|
export class BulkSchedulesResponseDto {
|
|
@ApiProperty() schedulesCreated: number;
|
|
@ApiProperty() errors: string[];
|
|
@ApiProperty() scheduleIds: string[];
|
|
}
|