99 lines
3.2 KiB
TypeScript
99 lines
3.2 KiB
TypeScript
import { QueryInterface, DataTypes } from 'sequelize';
|
||
|
||
/**
|
||
* Migration: Add skip-related fields to approval_levels table
|
||
* Purpose: Track approvers who were skipped by initiator
|
||
* Date: 2025-11-05
|
||
*/
|
||
|
||
export async function up(queryInterface: QueryInterface): Promise<void> {
|
||
// Check if table exists first
|
||
const tables = await queryInterface.showAllTables();
|
||
if (!tables.includes('approval_levels')) {
|
||
console.log('⚠️ approval_levels table does not exist yet, skipping...');
|
||
return;
|
||
}
|
||
|
||
// Get existing columns
|
||
const tableDescription = await queryInterface.describeTable('approval_levels');
|
||
|
||
// Add skip-related columns only if they don't exist
|
||
if (!tableDescription.is_skipped) {
|
||
await queryInterface.addColumn('approval_levels', 'is_skipped', {
|
||
type: DataTypes.BOOLEAN,
|
||
allowNull: false,
|
||
defaultValue: false,
|
||
comment: 'Indicates if this approver was skipped by initiator'
|
||
});
|
||
console.log(' ✅ Added is_skipped column');
|
||
}
|
||
|
||
if (!tableDescription.skipped_at) {
|
||
await queryInterface.addColumn('approval_levels', 'skipped_at', {
|
||
type: DataTypes.DATE,
|
||
allowNull: true,
|
||
comment: 'Timestamp when approver was skipped'
|
||
});
|
||
console.log(' ✅ Added skipped_at column');
|
||
}
|
||
|
||
if (!tableDescription.skipped_by) {
|
||
await queryInterface.addColumn('approval_levels', 'skipped_by', {
|
||
type: DataTypes.UUID,
|
||
allowNull: true,
|
||
references: {
|
||
model: 'users',
|
||
key: 'user_id'
|
||
},
|
||
onUpdate: 'CASCADE',
|
||
onDelete: 'SET NULL',
|
||
comment: 'User ID who skipped this approver'
|
||
});
|
||
console.log(' ✅ Added skipped_by column');
|
||
}
|
||
|
||
if (!tableDescription.skip_reason) {
|
||
await queryInterface.addColumn('approval_levels', 'skip_reason', {
|
||
type: DataTypes.TEXT,
|
||
allowNull: true,
|
||
comment: 'Reason for skipping this approver'
|
||
});
|
||
console.log(' ✅ Added skip_reason column');
|
||
}
|
||
|
||
// Check if index exists before creating
|
||
try {
|
||
const indexes: any[] = await queryInterface.showIndex('approval_levels') as any[];
|
||
const indexExists = Array.isArray(indexes) && indexes.some((idx: any) => idx.name === 'idx_approval_levels_skipped');
|
||
|
||
if (!indexExists) {
|
||
await queryInterface.addIndex('approval_levels', ['is_skipped'], {
|
||
name: 'idx_approval_levels_skipped',
|
||
where: {
|
||
is_skipped: true
|
||
}
|
||
});
|
||
console.log(' ✅ Added idx_approval_levels_skipped index');
|
||
}
|
||
} catch (error) {
|
||
// Index might already exist, which is fine
|
||
console.log(' ℹ️ Index already exists or could not be created');
|
||
}
|
||
|
||
console.log('✅ Skip-related fields migration completed');
|
||
}
|
||
|
||
export async function down(queryInterface: QueryInterface): Promise<void> {
|
||
// Remove index first
|
||
await queryInterface.removeIndex('approval_levels', 'idx_approval_levels_skipped');
|
||
|
||
// Remove columns
|
||
await queryInterface.removeColumn('approval_levels', 'skip_reason');
|
||
await queryInterface.removeColumn('approval_levels', 'skipped_by');
|
||
await queryInterface.removeColumn('approval_levels', 'skipped_at');
|
||
await queryInterface.removeColumn('approval_levels', 'is_skipped');
|
||
|
||
console.log('✅ Removed skip-related fields from approval_levels table');
|
||
}
|
||
|