// apps/edr-freight-api/src/modules/wagons/entities/wagon.entity.ts import { WagonStatus } from '@edr/types'; import { Entity, Column, ManyToOne, OneToMany, JoinColumn, Index } from 'typeorm'; import { BaseEntity } from '@edr/api-common'; import { Train } from '../../trains/entities/train.entity'; import { TrainSchedule } from '../../train-schedules/entities/train-schedule.entity'; import { TrainSetWagon } from '../../train-sets/entities/train-set-wagon.entity'; import { Container } from '../../container-management/entities/container.entity'; import { Yard } from '../../rule-engine/entities/yard.entity'; import { WagonType } from '../../wagon-types/entities/wagon-type.entity'; export const WAGON_STATUSES = [ WagonStatus.Available, WagonStatus.Assigned, WagonStatus.ImportReady, WagonStatus.ExportReady, WagonStatus.Maintenance, WagonStatus.Detained, WagonStatus.OutOfService, ] as const; export type WagonStatusType = (typeof WAGON_STATUSES)[number]; @Entity({ name: 'wagons', schema: 'freight' }) @Index(['currentYardId']) export class Wagon extends BaseEntity { @Column({ unique: true, name: 'wagon_number' }) wagonNumber!: string; @Column({ name: 'wagon_type_id', type: 'uuid' }) wagonTypeId!: string; /** Owns this wagon's spec: tare weight, payload capacity, length. */ @ManyToOne(() => WagonType) @JoinColumn({ name: 'wagon_type_id' }) wagonType?: WagonType; @Column({ name: 'train_id', type: 'uuid', nullable: true }) trainId!: string | null; @Column({ name: 'sequence_number', type: 'int', nullable: true }) sequenceNumber!: number | null; // Tare weight and payload capacity are properties of the wagon TYPE — read them // through `wagonType`, never off the individual wagon. /** EXPORT run number — odd, Ethiopia → Djibouti (e.g. 8001). Null until set. */ @Column({ name: 'export_train_number', type: 'varchar', length: 20, nullable: true }) exportTrainNumber!: string | null; /** IMPORT run number — even, Djibouti → Ethiopia (e.g. 8002). Null until set. */ @Column({ name: 'import_train_number', type: 'varchar', length: 20, nullable: true }) importTrainNumber!: string | null; @Column({ type: 'varchar', length: 20, default: WagonStatus.Available }) status!: WagonStatusType; @Column({ name: 'current_yard_id', type: 'uuid', nullable: true }) currentYardId!: string | null; @ManyToOne(() => Yard, { nullable: true, onDelete: 'SET NULL' }) @JoinColumn({ name: 'current_yard_id' }) currentYard?: Yard | null; @Column({ type: 'text', nullable: true }) notes!: string | null; @Column({ name: 'train_set_wagon_id', type: 'uuid', nullable: true }) trainSetWagonId!: string | null; @ManyToOne(() => TrainSetWagon, { nullable: true, onDelete: 'SET NULL' }) @JoinColumn({ name: 'train_set_wagon_id' }) trainSetWagon?: TrainSetWagon | null; @Column({ name: 'current_train_schedule_id', type: 'uuid', nullable: true }) currentTrainScheduleId!: string | null; @ManyToOne(() => TrainSchedule, { nullable: true, onDelete: 'SET NULL' }) @JoinColumn({ name: 'current_train_schedule_id' }) currentTrainSchedule?: TrainSchedule | null; /** Fleet master consist grouping — separate from operational train_schedules. */ @ManyToOne(() => Train, (train) => train.wagons, { onDelete: 'SET NULL' }) @JoinColumn({ name: 'train_id' }) train!: Train | null; // Relationship to Container @OneToMany(() => Container, (container) => container.wagon) containers!: Container[]; }