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 { // 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 { // 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'); }