feat(freight): basics of train scheduling

This commit is contained in:
Michael Abebe
2026-06-04 16:50:38 +03:00
parent ec0d789502
commit 8b3aaad5fd
41 changed files with 3147 additions and 12 deletions

View File

@@ -0,0 +1,26 @@
import { BaseEntity } from '@edr/api-common';
import { Entity, Index, JoinColumn, ManyToOne, Column } from 'typeorm';
import { Booking } from '../../bookings/entities/booking.entity';
import { TrainSchedule } from './train-schedule.entity';
@Entity({ schema: 'freight', name: 'train_schedule_bookings' })
@Index(['trainScheduleId', 'bookingId'], { unique: true })
@Index(['bookingId'], { unique: true })
export class TrainScheduleBooking extends BaseEntity {
@Column({ name: 'train_schedule_id', type: 'uuid' })
trainScheduleId!: string;
@ManyToOne(() => TrainSchedule, (trainSchedule) => trainSchedule.scheduleBookings, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'train_schedule_id' })
trainSchedule?: TrainSchedule;
@Column({ name: 'booking_id', type: 'uuid' })
bookingId!: string;
@ManyToOne(() => Booking)
@JoinColumn({ name: 'booking_id' })
booking?: Booking;
}

View File

@@ -0,0 +1,54 @@
import { BaseEntity } from '@edr/api-common';
import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm';
import { Yard } from '../../rule-engine/entities/yard.entity';
import { TrainSet } from '../../train-sets/entities/train-set.entity';
import { TrainScheduleBooking } from './train-schedule-booking.entity';
export const TRAIN_SCHEDULE_STATUSES = [
'DRAFT',
'SCHEDULED',
'DISPATCHED',
'ARRIVED',
'CANCELLED',
] as const;
export type TrainScheduleStatus = (typeof TRAIN_SCHEDULE_STATUSES)[number];
@Entity({ schema: 'freight', name: 'train_schedules' })
@Index(['scheduledDepartureDate'])
@Index(['status'])
export class TrainSchedule extends BaseEntity {
@Column({ name: 'train_set_id', type: 'uuid', unique: true })
trainSetId!: string;
@OneToOne(() => TrainSet, (trainSet) => trainSet.trainSchedule)
@JoinColumn({ name: 'train_set_id' })
trainSet?: TrainSet;
@Column({ name: 'origin_station_id', type: 'uuid' })
originStationId!: string;
@ManyToOne(() => Yard)
@JoinColumn({ name: 'origin_station_id' })
originStation?: Yard;
@Column({ name: 'destination_station_id', type: 'uuid' })
destinationStationId!: string;
@ManyToOne(() => Yard)
@JoinColumn({ name: 'destination_station_id' })
destinationStation?: Yard;
@Column({ name: 'scheduled_departure_date', type: 'timestamptz' })
scheduledDepartureDate!: Date;
@Column({ name: 'scheduled_arrival_date', type: 'timestamptz', nullable: true })
scheduledArrivalDate?: Date | null;
@Column({ name: 'status', type: 'varchar', length: 20, default: 'DRAFT' })
status!: TrainScheduleStatus;
@OneToMany(() => TrainScheduleBooking, (scheduleBooking) => scheduleBooking.trainSchedule)
scheduleBookings?: TrainScheduleBooking[];
}

View File

@@ -0,0 +1,26 @@
import { BaseEntity } from '@edr/api-common';
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
import { Booking } from '../../bookings/entities/booking.entity';
import { TrainSetWagon } from '../../train-sets/entities/train-set-wagon.entity';
@Entity({ schema: 'freight', name: 'wagon_booking_allocations' })
@Index(['trainSetWagonId', 'bookingId'])
export class WagonBookingAllocation extends BaseEntity {
@Column({ name: 'train_set_wagon_id', type: 'uuid' })
trainSetWagonId!: string;
@ManyToOne(() => TrainSetWagon, (wagon) => wagon.allocations, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'train_set_wagon_id' })
trainSetWagon?: TrainSetWagon;
@Column({ name: 'booking_id', type: 'uuid' })
bookingId!: string;
@ManyToOne(() => Booking)
@JoinColumn({ name: 'booking_id' })
booking?: Booking;
@Column({ name: 'allocated_weight_tons', type: 'numeric', precision: 10, scale: 3 })
allocatedWeightTons!: number;
}

View File

@@ -0,0 +1,16 @@
import { BaseRepository } from '@edr/api-common';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { TrainScheduleBooking } from './entities/train-schedule-booking.entity';
@Injectable()
export class TrainScheduleBookingsRepository extends BaseRepository<TrainScheduleBooking> {
constructor(
@InjectRepository(TrainScheduleBooking)
repository: Repository<TrainScheduleBooking>,
) {
super(repository);
}
}

View File

@@ -0,0 +1,24 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TrainScheduleBooking } from './entities/train-schedule-booking.entity';
import { TrainSchedule } from './entities/train-schedule.entity';
import { WagonBookingAllocation } from './entities/wagon-booking-allocation.entity';
import { TrainScheduleBookingsRepository } from './train-schedule-bookings.repository';
import { TrainSchedulesRepository } from './train-schedules.repository';
import { WagonBookingAllocationsRepository } from './wagon-booking-allocations.repository';
@Module({
imports: [TypeOrmModule.forFeature([TrainSchedule, TrainScheduleBooking, WagonBookingAllocation])],
providers: [
TrainSchedulesRepository,
TrainScheduleBookingsRepository,
WagonBookingAllocationsRepository,
],
exports: [
TrainSchedulesRepository,
TrainScheduleBookingsRepository,
WagonBookingAllocationsRepository,
],
})
export class TrainSchedulesModule {}

View File

@@ -0,0 +1,16 @@
import { BaseRepository } from '@edr/api-common';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { TrainSchedule } from './entities/train-schedule.entity';
@Injectable()
export class TrainSchedulesRepository extends BaseRepository<TrainSchedule> {
constructor(
@InjectRepository(TrainSchedule)
repository: Repository<TrainSchedule>,
) {
super(repository);
}
}

View File

@@ -0,0 +1,16 @@
import { BaseRepository } from '@edr/api-common';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { WagonBookingAllocation } from './entities/wagon-booking-allocation.entity';
@Injectable()
export class WagonBookingAllocationsRepository extends BaseRepository<WagonBookingAllocation> {
constructor(
@InjectRepository(WagonBookingAllocation)
repository: Repository<WagonBookingAllocation>,
) {
super(repository);
}
}