add GL operations for customs risk assignment, duty advising, and incident reporting

This commit is contained in:
Marshal
2026-06-28 16:09:45 +00:00
parent 7c744352d1
commit e1d54746c2
31 changed files with 1879 additions and 29 deletions

View File

@@ -0,0 +1,65 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
/**
* Global Logistics Phase-2 operational features (docs/new-doc.md §11§13, gap
* matrix #14/#16/#17/#18):
* - `clearance_milestones.metadata` — structured payload for RISK_ASSIGNED
* (risk level) and DUTY_TAXES_ADVISED (amount, currency, declaration serial)
* - `bookings.gl_station_yard_id` / `gl_assigned_staff_id` / `gl_assigned_at`
* — station routing + staff binding (GL US-02)
* - `freight.clearance_incidents` — cargo exception/damage reports with photos
* (GL Import US-07)
*/
export class AddGlOperations1825000000000 implements MigrationInterface {
name = 'AddGlOperations1825000000000';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE freight.clearance_milestones ADD COLUMN IF NOT EXISTS metadata JSONB;`,
);
await queryRunner.query(
`ALTER TABLE freight.bookings ADD COLUMN IF NOT EXISTS gl_station_yard_id UUID;`,
);
await queryRunner.query(
`ALTER TABLE freight.bookings ADD COLUMN IF NOT EXISTS gl_assigned_staff_id UUID;`,
);
await queryRunner.query(
`ALTER TABLE freight.bookings ADD COLUMN IF NOT EXISTS gl_assigned_at TIMESTAMPTZ;`,
);
await queryRunner.query(`
CREATE TABLE IF NOT EXISTS freight.clearance_incidents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
booking_id UUID NOT NULL REFERENCES freight.bookings(id) ON DELETE CASCADE,
incident_type VARCHAR(32) NOT NULL,
description TEXT NOT NULL,
photo_file_ids JSONB NOT NULL DEFAULT '[]',
reported_by_user_id UUID,
reported_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMPTZ
);
`);
await queryRunner.query(
`CREATE INDEX IF NOT EXISTS idx_clearance_incidents_booking ON freight.clearance_incidents(booking_id);`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE IF EXISTS freight.clearance_incidents CASCADE;`);
await queryRunner.query(
`ALTER TABLE freight.bookings DROP COLUMN IF EXISTS gl_assigned_at;`,
);
await queryRunner.query(
`ALTER TABLE freight.bookings DROP COLUMN IF EXISTS gl_assigned_staff_id;`,
);
await queryRunner.query(
`ALTER TABLE freight.bookings DROP COLUMN IF EXISTS gl_station_yard_id;`,
);
await queryRunner.query(
`ALTER TABLE freight.clearance_milestones DROP COLUMN IF EXISTS metadata;`,
);
}
}