mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
Intercity cargo is loaded at its origin yard and unloaded at its destination, but
only some yards have the equipment. EDR's facilities are Indode, Sebeta, Modjo,
Adama and Dire Dawa — and the set grows, so it has to be data.
- yards.has_facility marks a yard as a load/unload point; the new yard_facilities
record says what it can do. Only Indode stores cargo (has_warehouse), so only it
accrues storage/demurrage — the rest just move cargo on and off the train.
- facility_handling_events records each load/unload and carries its GRN.
warehouse_inventory cannot: its warehouse/yard/zone are NOT NULL, so a facility
without a warehouse could never have a row. inventory_id links to the storage
record when there is one.
- YardFacilitiesService.facilityForYard is the single resolver the handling flows
share, so they cannot drift on what a facility is.
- The seeder flags EXISTING yards and creates none. The codes are historical and
do not read like the facility names — Indode is KALITY ("Gelan Multi Purpose
Port (Indode)") and Sebeta is LEGACY_DEST — so it maps by code. Creating fresh
INDODE/SEBETA yards would have split data that routes and bookings already
reference.
Negad is deliberately absent: NAGAD ("DCT/SGDT") is in Djibouti while
NEGAD_FY_BCC is in Ethiopia and inactive, and which one is the intercity facility
is unsettled.
No behaviour change yet — nothing reads has_facility until the gate lands.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
36 lines
1.3 KiB
TypeScript
36 lines
1.3 KiB
TypeScript
import { BaseEntity } from '@edr/api-common';
|
|
import { YardCountry } from '@edr/types';
|
|
import { Column, Entity, Index } from 'typeorm';
|
|
|
|
@Entity({ schema: 'freight', name: 'yards' })
|
|
@Index(['code'])
|
|
@Index(['country'])
|
|
@Index(['isActive'])
|
|
export class Yard extends BaseEntity {
|
|
@Column({ name: 'code', type: 'varchar', length: 20, unique: true })
|
|
code!: string;
|
|
|
|
@Column({ name: 'label', type: 'varchar', length: 100 })
|
|
label!: string;
|
|
|
|
// Constrained to YardCountry by DTO validation + a DB CHECK constraint;
|
|
// route/schedule trade direction is derived from this value. Typed as the
|
|
// enum's literal values so plain strings from seeds/queries still fit.
|
|
@Column({ name: 'country', type: 'varchar', length: 50 })
|
|
country!: `${YardCountry}`;
|
|
|
|
@Column({ name: 'is_active', type: 'boolean', default: true })
|
|
isActive!: boolean;
|
|
|
|
/**
|
|
* This yard has the equipment to load/unload cargo. Intercity bookings can only
|
|
* be loaded at their origin and unloaded at their destination where this is
|
|
* true. What the facility can do lives on the YardFacility record.
|
|
*/
|
|
@Column({ name: 'has_facility', type: 'boolean', default: false })
|
|
hasFacility!: boolean;
|
|
|
|
@Column({ name: 'display_order', type: 'int', default: 1 })
|
|
displayOrder!: number;
|
|
}
|