From 398bc9330e6a4bf2ac48de2b11ef2c1e492417a2 Mon Sep 17 00:00:00 2001 From: natib21 Date: Thu, 18 Jun 2026 09:11:10 +0000 Subject: [PATCH] fix migration --- ...1750000000001-AddFacilityIdToWarehouses.ts | 22 +++- ...50000000002-AddProofOfDeliveryToCargoes.ts | 41 +++++-- .../1750000000003-AddWarehouseInspection.ts | 101 +++++++++++------- ...00000-AddWarehouseAllocationAndFeeRules.ts | 64 ++++++++--- 4 files changed, 163 insertions(+), 65 deletions(-) diff --git a/apps/edr-freight-api/src/migrations/1750000000001-AddFacilityIdToWarehouses.ts b/apps/edr-freight-api/src/migrations/1750000000001-AddFacilityIdToWarehouses.ts index 413fd6126..82f2d92fd 100644 --- a/apps/edr-freight-api/src/migrations/1750000000001-AddFacilityIdToWarehouses.ts +++ b/apps/edr-freight-api/src/migrations/1750000000001-AddFacilityIdToWarehouses.ts @@ -2,6 +2,18 @@ import { MigrationInterface, QueryRunner, TableColumn, TableForeignKey } from 't export class AddFacilityIdToWarehouses1750000000001 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { + const table = await queryRunner.getTable('freight.warehouses'); + if (!table) { + // warehouses table doesn't exist yet, skip this migration + return; + } + + const hasColumn = table.columns.some((col) => col.name === 'facility_id'); + if (hasColumn) { + // Column already exists, skip + return; + } + await queryRunner.addColumn( 'freight.warehouses', new TableColumn({ @@ -25,10 +37,16 @@ export class AddFacilityIdToWarehouses1750000000001 implements MigrationInterfac public async down(queryRunner: QueryRunner): Promise { const table = await queryRunner.getTable('freight.warehouses'); - const foreignKey = table?.foreignKeys.find((fk) => fk.columnNames.includes('facility_id')); + if (!table) { + return; + } + const foreignKey = table.foreignKeys.find((fk) => fk.columnNames.includes('facility_id')); if (foreignKey) { await queryRunner.dropForeignKey('freight.warehouses', foreignKey); } - await queryRunner.dropColumn('freight.warehouses', 'facility_id'); + const hasColumn = table.columns.some((col) => col.name === 'facility_id'); + if (hasColumn) { + await queryRunner.dropColumn('freight.warehouses', 'facility_id'); + } } } diff --git a/apps/edr-freight-api/src/migrations/1750000000002-AddProofOfDeliveryToCargoes.ts b/apps/edr-freight-api/src/migrations/1750000000002-AddProofOfDeliveryToCargoes.ts index 5df498712..67957f437 100644 --- a/apps/edr-freight-api/src/migrations/1750000000002-AddProofOfDeliveryToCargoes.ts +++ b/apps/edr-freight-api/src/migrations/1750000000002-AddProofOfDeliveryToCargoes.ts @@ -6,14 +6,43 @@ import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm'; */ export class AddProofOfDeliveryToCargoes1750000000002 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { - await queryRunner.addColumns('freight.cargoes', [ - new TableColumn({ name: 'receiver_name', type: 'varchar', isNullable: true }), - new TableColumn({ name: 'delivered_at', type: 'timestamp', isNullable: true }), - new TableColumn({ name: 'delivery_remarks', type: 'text', isNullable: true }), - ]); + const table = await queryRunner.getTable('freight.cargoes'); + if (!table) { + // cargoes table doesn't exist yet, skip this migration + return; + } + + const columnsToAdd = [ + { name: 'receiver_name', type: 'varchar', isNullable: true }, + { name: 'delivered_at', type: 'timestamp', isNullable: true }, + { name: 'delivery_remarks', type: 'text', isNullable: true }, + ]; + + const columnsToCreate = columnsToAdd.filter( + (col) => !table.columns.some((c) => c.name === col.name), + ); + + if (columnsToCreate.length > 0) { + await queryRunner.addColumns( + 'freight.cargoes', + columnsToCreate.map((col) => new TableColumn(col)), + ); + } } public async down(queryRunner: QueryRunner): Promise { - await queryRunner.dropColumns('freight.cargoes', ['receiver_name', 'delivered_at', 'delivery_remarks']); + const table = await queryRunner.getTable('freight.cargoes'); + if (!table) { + return; + } + + const columnNames = ['receiver_name', 'delivered_at', 'delivery_remarks']; + const columnsToRemove = columnNames.filter((name) => + table.columns.some((c) => c.name === name), + ); + + if (columnsToRemove.length > 0) { + await queryRunner.dropColumns('freight.cargoes', columnsToRemove); + } } } diff --git a/apps/edr-freight-api/src/migrations/1750000000003-AddWarehouseInspection.ts b/apps/edr-freight-api/src/migrations/1750000000003-AddWarehouseInspection.ts index ae5a1625a..88ef8d3a5 100644 --- a/apps/edr-freight-api/src/migrations/1750000000003-AddWarehouseInspection.ts +++ b/apps/edr-freight-api/src/migrations/1750000000003-AddWarehouseInspection.ts @@ -6,51 +6,70 @@ import { MigrationInterface, QueryRunner, Table, TableColumn } from 'typeorm'; export class AddWarehouseInspection1750000000003 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { // inventory.inspection_status - await queryRunner.addColumn( - 'freight.warehouse_inventory', - new TableColumn({ name: 'inspection_status', type: 'varchar', length: '20', isNullable: true }), - ); + const inventoryTable = await queryRunner.getTable('freight.warehouse_inventory'); + if (inventoryTable) { + const hasColumn = inventoryTable.columns.some((col) => col.name === 'inspection_status'); + if (!hasColumn) { + await queryRunner.addColumn( + 'freight.warehouse_inventory', + new TableColumn({ name: 'inspection_status', type: 'varchar', length: '20', isNullable: true }), + ); + } + } // warehouse_inspection_reports table - await queryRunner.createTable( - new Table({ - schema: 'freight', - name: 'warehouse_inspection_reports', - columns: [ - { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' }, - { name: 'inventory_id', type: 'uuid' }, - { name: 'booking_id', type: 'uuid', isNullable: true }, - { name: 'customer_id', type: 'uuid', isNullable: true }, - { name: 'report_type', type: 'varchar', length: '32', default: "'INSPECTION'" }, - { name: 'inspection_status', type: 'varchar', length: '20', default: "'NEEDS_REVIEW'" }, - { name: 'has_damage', type: 'boolean', default: false }, - { name: 'damage_description', type: 'text', isNullable: true }, - { name: 'has_weight_loss', type: 'boolean', default: false }, - { name: 'expected_weight', type: 'numeric', precision: 14, scale: 3, isNullable: true }, - { name: 'actual_weight', type: 'numeric', precision: 14, scale: 3, isNullable: true }, - { name: 'weight_loss', type: 'numeric', precision: 14, scale: 3, isNullable: true }, - { name: 'weight_loss_unit', type: 'varchar', length: '12', isNullable: true }, - { name: 'has_missing_items', type: 'boolean', default: false }, - { name: 'missing_items_description', type: 'text', isNullable: true }, - { name: 'remarks', type: 'text', isNullable: true }, - { name: 'inspected_by_id', type: 'uuid', isNullable: true }, - { name: 'inspected_at', type: 'timestamptz', isNullable: true }, - { name: 'created_at', type: 'timestamptz', default: 'now()' }, - { name: 'updated_at', type: 'timestamptz', default: 'now()' }, - { name: 'deleted_at', type: 'timestamptz', isNullable: true }, - ], - indices: [ - { name: 'idx_wir_inventory', columnNames: ['inventory_id'] }, - { name: 'idx_wir_booking', columnNames: ['booking_id'] }, - { name: 'idx_wir_status', columnNames: ['inspection_status'] }, - ], - }), - true, - ); + const inspectionTable = await queryRunner.getTable('freight.warehouse_inspection_reports'); + if (!inspectionTable) { + await queryRunner.createTable( + new Table({ + schema: 'freight', + name: 'warehouse_inspection_reports', + columns: [ + { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' }, + { name: 'inventory_id', type: 'uuid' }, + { name: 'booking_id', type: 'uuid', isNullable: true }, + { name: 'customer_id', type: 'uuid', isNullable: true }, + { name: 'report_type', type: 'varchar', length: '32', default: "'INSPECTION'" }, + { name: 'inspection_status', type: 'varchar', length: '20', default: "'NEEDS_REVIEW'" }, + { name: 'has_damage', type: 'boolean', default: false }, + { name: 'damage_description', type: 'text', isNullable: true }, + { name: 'has_weight_loss', type: 'boolean', default: false }, + { name: 'expected_weight', type: 'numeric', precision: 14, scale: 3, isNullable: true }, + { name: 'actual_weight', type: 'numeric', precision: 14, scale: 3, isNullable: true }, + { name: 'weight_loss', type: 'numeric', precision: 14, scale: 3, isNullable: true }, + { name: 'weight_loss_unit', type: 'varchar', length: '12', isNullable: true }, + { name: 'has_missing_items', type: 'boolean', default: false }, + { name: 'missing_items_description', type: 'text', isNullable: true }, + { name: 'remarks', type: 'text', isNullable: true }, + { name: 'inspected_by_id', type: 'uuid', isNullable: true }, + { name: 'inspected_at', type: 'timestamptz', isNullable: true }, + { name: 'created_at', type: 'timestamptz', default: 'now()' }, + { name: 'updated_at', type: 'timestamptz', default: 'now()' }, + { name: 'deleted_at', type: 'timestamptz', isNullable: true }, + ], + indices: [ + { name: 'idx_wir_inventory', columnNames: ['inventory_id'] }, + { name: 'idx_wir_booking', columnNames: ['booking_id'] }, + { name: 'idx_wir_status', columnNames: ['inspection_status'] }, + ], + }), + true, + ); + } } public async down(queryRunner: QueryRunner): Promise { - await queryRunner.dropTable('freight.warehouse_inspection_reports', true); - await queryRunner.dropColumn('freight.warehouse_inventory', 'inspection_status'); + const inspectionTable = await queryRunner.getTable('freight.warehouse_inspection_reports'); + if (inspectionTable) { + await queryRunner.dropTable('freight.warehouse_inspection_reports', true); + } + + const inventoryTable = await queryRunner.getTable('freight.warehouse_inventory'); + if (inventoryTable) { + const hasColumn = inventoryTable.columns.some((col) => col.name === 'inspection_status'); + if (hasColumn) { + await queryRunner.dropColumn('freight.warehouse_inventory', 'inspection_status'); + } + } } } diff --git a/apps/edr-freight-api/src/migrations/1790000000000-AddWarehouseAllocationAndFeeRules.ts b/apps/edr-freight-api/src/migrations/1790000000000-AddWarehouseAllocationAndFeeRules.ts index 125725400..05b1259f4 100644 --- a/apps/edr-freight-api/src/migrations/1790000000000-AddWarehouseAllocationAndFeeRules.ts +++ b/apps/edr-freight-api/src/migrations/1790000000000-AddWarehouseAllocationAndFeeRules.ts @@ -70,24 +70,56 @@ export class AddWarehouseAllocationAndFeeRules1790000000000 implements Migration true, ); - await queryRunner.addColumns('freight.warehouse_inventory', [ - new TableColumn({ name: 'inspection_started_at', type: 'timestamptz', isNullable: true }), - new TableColumn({ name: 'inspection_completed_at', type: 'timestamptz', isNullable: true }), - new TableColumn({ name: 'ready_for_pickup_at', type: 'timestamptz', isNullable: true }), - new TableColumn({ name: 'release_date', type: 'timestamptz', isNullable: true }), - new TableColumn({ name: 'gate_cleared_at', type: 'timestamptz', isNullable: true }), - ]); + const inventoryTable = await queryRunner.getTable('freight.warehouse_inventory'); + if (inventoryTable) { + const columnsToAdd = [ + { name: 'inspection_started_at', type: 'timestamptz', isNullable: true }, + { name: 'inspection_completed_at', type: 'timestamptz', isNullable: true }, + { name: 'ready_for_pickup_at', type: 'timestamptz', isNullable: true }, + { name: 'release_date', type: 'timestamptz', isNullable: true }, + { name: 'gate_cleared_at', type: 'timestamptz', isNullable: true }, + ]; + + const columnsToCreate = columnsToAdd.filter( + (col) => !inventoryTable.columns.some((c) => c.name === col.name), + ); + + if (columnsToCreate.length > 0) { + await queryRunner.addColumns( + 'freight.warehouse_inventory', + columnsToCreate.map((col) => new TableColumn(col)), + ); + } + } } public async down(queryRunner: QueryRunner): Promise { - await queryRunner.dropColumns('freight.warehouse_inventory', [ - 'inspection_started_at', - 'inspection_completed_at', - 'ready_for_pickup_at', - 'release_date', - 'gate_cleared_at', - ]); - await queryRunner.dropTable('freight.warehouse_fee_rules', true); - await queryRunner.dropTable('freight.warehouse_allocation_rules', true); + const inventoryTable = await queryRunner.getTable('freight.warehouse_inventory'); + if (inventoryTable) { + const columnNames = [ + 'inspection_started_at', + 'inspection_completed_at', + 'ready_for_pickup_at', + 'release_date', + 'gate_cleared_at', + ]; + const columnsToRemove = columnNames.filter((name) => + inventoryTable.columns.some((c) => c.name === name), + ); + + if (columnsToRemove.length > 0) { + await queryRunner.dropColumns('freight.warehouse_inventory', columnsToRemove); + } + } + + const feeRulesTable = await queryRunner.getTable('freight.warehouse_fee_rules'); + if (feeRulesTable) { + await queryRunner.dropTable('freight.warehouse_fee_rules', true); + } + + const allocationRulesTable = await queryRunner.getTable('freight.warehouse_allocation_rules'); + if (allocationRulesTable) { + await queryRunner.dropTable('freight.warehouse_allocation_rules', true); + } } }