mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 12:41:04 +00:00
214 lines
5.7 KiB
TypeScript
214 lines
5.7 KiB
TypeScript
import { BaseEntity } from '@edr/api-common';
|
|
import { Column, Entity } from 'typeorm';
|
|
|
|
/**
|
|
* numeric comes back from pg as a string. Every value here is arithmetic in a
|
|
* report expression, so convert on read rather than making each caller do it.
|
|
*/
|
|
const asNumber = {
|
|
to: (value: number) => value,
|
|
from: (value: string | null) => (value === null ? null : Number(value)),
|
|
};
|
|
|
|
/**
|
|
* Single-row table holding the railway's operating standards — the numbers the
|
|
* operations reports measure actual performance against. Same single-row shape
|
|
* as `logo_settings` and `exchange_settings`; the app never inserts a second row.
|
|
*
|
|
* These live in the database rather than in a constants file because the
|
|
* business treats them as tunable (the corridor standard is explicitly
|
|
* described as "flexible"), and a planner must be able to change one without a
|
|
* deployment.
|
|
*/
|
|
@Entity({ schema: 'freight', name: 'operations_standards' })
|
|
export class OperationsStandard extends BaseEntity {
|
|
/** Standard time a train may stand at an Ethiopian station, in hours. */
|
|
@Column({
|
|
name: 'station_standard_hours_ethiopia',
|
|
type: 'numeric',
|
|
precision: 6,
|
|
scale: 2,
|
|
default: 10,
|
|
transformer: asNumber,
|
|
})
|
|
stationStandardHoursEthiopia!: number;
|
|
|
|
/** Standard time a train may stand at a Djibouti station, in hours. */
|
|
@Column({
|
|
name: 'station_standard_hours_djibouti',
|
|
type: 'numeric',
|
|
precision: 6,
|
|
scale: 2,
|
|
default: 13,
|
|
transformer: asNumber,
|
|
})
|
|
stationStandardHoursDjibouti!: number;
|
|
|
|
/** Container turn-around cycle: 10 + 21 + 13 + 21. */
|
|
@Column({
|
|
name: 'cycle_standard_hours_container',
|
|
type: 'numeric',
|
|
precision: 6,
|
|
scale: 2,
|
|
default: 65,
|
|
transformer: asNumber,
|
|
})
|
|
cycleStandardHoursContainer!: number;
|
|
|
|
/** Bulk cycle via DMP: 13 + 21 + 33 + 21. */
|
|
@Column({
|
|
name: 'cycle_standard_hours_bulk_dmp',
|
|
type: 'numeric',
|
|
precision: 6,
|
|
scale: 2,
|
|
default: 88,
|
|
transformer: asNumber,
|
|
})
|
|
cycleStandardHoursBulkDmp!: number;
|
|
|
|
/** Bulk cycle via Negad freight yard: 13 + 21 + 41 + 21. */
|
|
@Column({
|
|
name: 'cycle_standard_hours_bulk_nagad',
|
|
type: 'numeric',
|
|
precision: 6,
|
|
scale: 2,
|
|
default: 96,
|
|
transformer: asNumber,
|
|
})
|
|
cycleStandardHoursBulkNagad!: number;
|
|
|
|
/** Bulk cycle via BCC: 13 + 21 + 41 + 21. */
|
|
@Column({
|
|
name: 'cycle_standard_hours_bulk_bcc',
|
|
type: 'numeric',
|
|
precision: 6,
|
|
scale: 2,
|
|
default: 96,
|
|
transformer: asNumber,
|
|
})
|
|
cycleStandardHoursBulkBcc!: number;
|
|
|
|
/**
|
|
* Standard running time for one corridor leg, used when the yard pair has no
|
|
* `yard_distances.standard_hours` of its own.
|
|
*/
|
|
@Column({
|
|
name: 'default_leg_standard_hours',
|
|
type: 'numeric',
|
|
precision: 6,
|
|
scale: 2,
|
|
default: 21,
|
|
transformer: asNumber,
|
|
})
|
|
defaultLegStandardHours!: number;
|
|
|
|
/** Grace on top of the leg standard before a train counts as delayed. */
|
|
@Column({ name: 'delay_tolerance_minutes', type: 'int', default: 30 })
|
|
delayToleranceMinutes!: number;
|
|
|
|
/** Charged tonnage per laden 20ft container. */
|
|
@Column({
|
|
name: 'charged_tons_full_20ft',
|
|
type: 'numeric',
|
|
precision: 8,
|
|
scale: 2,
|
|
default: 20,
|
|
transformer: asNumber,
|
|
})
|
|
chargedTonsFull20ft!: number;
|
|
|
|
/** Charged tonnage per laden 40ft container. */
|
|
@Column({
|
|
name: 'charged_tons_full_40ft',
|
|
type: 'numeric',
|
|
precision: 8,
|
|
scale: 2,
|
|
default: 40,
|
|
transformer: asNumber,
|
|
})
|
|
chargedTonsFull40ft!: number;
|
|
|
|
/** Charged tonnage per empty 20ft container. */
|
|
@Column({
|
|
name: 'charged_tons_empty_20ft',
|
|
type: 'numeric',
|
|
precision: 8,
|
|
scale: 2,
|
|
default: 2.24,
|
|
transformer: asNumber,
|
|
})
|
|
chargedTonsEmpty20ft!: number;
|
|
|
|
/** Charged tonnage per empty 40ft container. */
|
|
@Column({
|
|
name: 'charged_tons_empty_40ft',
|
|
type: 'numeric',
|
|
precision: 8,
|
|
scale: 2,
|
|
default: 3.88,
|
|
transformer: asNumber,
|
|
})
|
|
chargedTonsEmpty40ft!: number;
|
|
|
|
/** Charged tonnage per wagon of steel, fertilizer, rice, sugar, livestock. */
|
|
@Column({
|
|
name: 'charged_tons_per_wagon_general',
|
|
type: 'numeric',
|
|
precision: 8,
|
|
scale: 2,
|
|
default: 70,
|
|
transformer: asNumber,
|
|
})
|
|
chargedTonsPerWagonGeneral!: number;
|
|
|
|
/** Charged tonnage per wagon of vegetables, milk, meat and other perishables. */
|
|
@Column({
|
|
name: 'charged_tons_per_wagon_perishable',
|
|
type: 'numeric',
|
|
precision: 8,
|
|
scale: 2,
|
|
default: 38,
|
|
transformer: asNumber,
|
|
})
|
|
chargedTonsPerWagonPerishable!: number;
|
|
|
|
/**
|
|
* Wagons in a full trainset when the cargo type has no
|
|
* `cargo_types.full_trainset_wagons` of its own.
|
|
*/
|
|
@Column({ name: 'default_full_trainset_wagons', type: 'int', default: 50 })
|
|
defaultFullTrainsetWagons!: number;
|
|
|
|
/**
|
|
* Standard loading-and-unloading time for a container train's stop, in hours.
|
|
*
|
|
* Null until a planner sets it, and deliberately so: the reporting spec names
|
|
* no handling standard, so an unset value reports no rate rather than judging
|
|
* a train against a guess. Same for the bulk figure below.
|
|
*/
|
|
@Column({
|
|
name: 'handling_standard_hours_container',
|
|
type: 'numeric',
|
|
precision: 6,
|
|
scale: 2,
|
|
nullable: true,
|
|
transformer: asNumber,
|
|
})
|
|
handlingStandardHoursContainer?: number | null;
|
|
|
|
/** Standard loading-and-unloading time for a bulk train's stop, in hours. */
|
|
@Column({
|
|
name: 'handling_standard_hours_bulk',
|
|
type: 'numeric',
|
|
precision: 6,
|
|
scale: 2,
|
|
nullable: true,
|
|
transformer: asNumber,
|
|
})
|
|
handlingStandardHoursBulk?: number | null;
|
|
|
|
/** IAM user id of the last operator to change a standard. */
|
|
@Column({ name: 'updated_by_id', type: 'uuid', nullable: true })
|
|
updatedById?: string | null;
|
|
}
|