import { MigrationInterface, QueryRunner } from 'typeorm'; /** * Pre-ITMLS baseline for fresh databases. Older environments created `freight.bookings` * via synchronize or manual SQL; ItmlsFullSchemaRewrite only ALTERs that table. */ export class CreateFreightLegacyBaseline1748550000000 implements MigrationInterface { name = 'CreateFreightLegacyBaseline1748550000000'; public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(`CREATE SCHEMA IF NOT EXISTS freight`); await queryRunner.query(` DO $$ BEGIN CREATE TYPE freight.train_status AS ENUM ( 'AVAILABLE', 'SCHEDULED', 'IN_SERVICE', 'UNDER_MAINTENANCE', 'OUT_OF_SERVICE' ); EXCEPTION WHEN duplicate_object THEN NULL; END $$; `); await queryRunner.query(` CREATE TABLE IF NOT EXISTS freight.trains ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), code VARCHAR(32) NOT NULL UNIQUE, capacity_tons NUMERIC(10, 2) NOT NULL DEFAULT 0, status freight.train_status NOT NULL DEFAULT 'AVAILABLE', notes TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), deleted_at TIMESTAMPTZ ); `); await queryRunner.query(` CREATE TABLE IF NOT EXISTS freight.bookings ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), reference VARCHAR(64) NOT NULL UNIQUE, customer_id UUID NOT NULL, train_id UUID, status VARCHAR(40) NOT NULL DEFAULT 'DRAFT', scheduled_date TIMESTAMPTZ NOT NULL DEFAULT now(), total_amount NUMERIC(14, 2) NOT NULL DEFAULT 0, payment_status VARCHAR(20) NOT NULL DEFAULT 'PENDING', contract_type VARCHAR(20) NOT NULL DEFAULT 'SPOT', previous_contract_id UUID, trade_direction VARCHAR(10) NOT NULL DEFAULT 'IMPORT', equipment_return VARCHAR(20) NOT NULL DEFAULT 'RETURN', first_mile_pickup_address TEXT, last_mile_delivery_address TEXT, cargo_total_weight_vgm NUMERIC(12, 3) NOT NULL DEFAULT 0, is_hazardous BOOLEAN NOT NULL DEFAULT false, payment_currency VARCHAR(5) NOT NULL DEFAULT 'USD', start_date DATE, end_date DATE, financial_terms TEXT, version_number INT NOT NULL DEFAULT 1, approved_by_staff_id UUID, approved_by_staff_at TIMESTAMPTZ, signed_by_director_id UUID, signed_by_director_at TIMESTAMPTZ, signed_by_ceo_id UUID, signed_by_ceo_at TIMESTAMPTZ, priority_score INT NOT NULL DEFAULT 0, allow_consolidation BOOLEAN NOT NULL DEFAULT false, consolidation_partner_id UUID, origin_station VARCHAR(255), destination_station VARCHAR(255), service_type VARCHAR(100), freight_type VARCHAR(100), freight_subtype VARCHAR(255), containers JSONB, first_mile_enabled BOOLEAN DEFAULT false, last_mile_enabled BOOLEAN DEFAULT false, is_refrigerated BOOLEAN DEFAULT false, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), deleted_at TIMESTAMPTZ ); `); } public async down(queryRunner: QueryRunner): Promise { await queryRunner.query(`DROP TABLE IF EXISTS freight.bookings CASCADE`); await queryRunner.query(`DROP TABLE IF EXISTS freight.trains CASCADE`); await queryRunner.query(`DROP TYPE IF EXISTS freight.train_status`); } }