module.exports = { /** * @param {QueryInterface} queryInterface * @param {Sequelize} Sequelize * @returns {Promise} */ async up(queryInterface, Sequelize) { /** * @type {Transaction} */ const transaction = await queryInterface.sequelize.transaction(); try { await queryInterface.createTable('users', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('roles', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('permissions', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('suppliers', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('categories', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('units', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('products', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('warehouses', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('storage_locations', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('inventory_items', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('stock_movements', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('stock_movement_lines', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('stock_counts', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('stock_count_lines', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('reorder_rules', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.createTable('alerts', { id: { type: Sequelize.DataTypes.UUID, defaultValue: Sequelize.DataTypes.UUIDV4, primaryKey: true, }, createdById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, updatedById: { type: Sequelize.DataTypes.UUID, references: { key: 'id', model: 'users', }, }, createdAt: { type: Sequelize.DataTypes.DATE }, updatedAt: { type: Sequelize.DataTypes.DATE }, deletedAt: { type: Sequelize.DataTypes.DATE }, importHash: { type: Sequelize.DataTypes.STRING(255), allowNull: true, unique: true, }, }, { transaction }); await queryInterface.addColumn( 'users', 'firstName', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'users', 'lastName', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'users', 'phoneNumber', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'users', 'email', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'users', 'disabled', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'users', 'password', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'users', 'emailVerified', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'users', 'emailVerificationToken', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'users', 'emailVerificationTokenExpiresAt', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'users', 'passwordResetToken', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'users', 'passwordResetTokenExpiresAt', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'users', 'provider', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'users', 'app_roleId', { type: Sequelize.DataTypes.UUID, references: { model: 'roles', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'roles', 'name', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'roles', 'role_customization', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'permissions', 'name', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'suppliers', 'name', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'suppliers', 'email', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'suppliers', 'phone', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'suppliers', 'address', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'suppliers', 'tax_number', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'suppliers', 'is_active', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'suppliers', 'notes', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'categories', 'name', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'categories', 'code', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'categories', 'description', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'categories', 'parent_categoryId', { type: Sequelize.DataTypes.UUID, references: { model: 'categories', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'categories', 'is_active', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'units', 'name', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'units', 'symbol', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'units', 'precision', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'units', 'is_active', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'products', 'name', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'products', 'sku', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'products', 'barcode', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'products', 'categoryId', { type: Sequelize.DataTypes.UUID, references: { model: 'categories', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'products', 'unitId', { type: Sequelize.DataTypes.UUID, references: { model: 'units', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'products', 'default_supplierId', { type: Sequelize.DataTypes.UUID, references: { model: 'suppliers', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'products', 'cost_price', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'products', 'sale_price', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'products', 'reorder_point', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'products', 'reorder_quantity', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'products', 'lead_time_days', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'products', 'is_serialized', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'products', 'is_active', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'products', 'description', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'warehouses', 'name', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'warehouses', 'code', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'warehouses', 'address', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'warehouses', 'is_active', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'warehouses', 'notes', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'storage_locations', 'name', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'storage_locations', 'code', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'storage_locations', 'warehouseId', { type: Sequelize.DataTypes.UUID, references: { model: 'warehouses', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'storage_locations', 'parent_locationId', { type: Sequelize.DataTypes.UUID, references: { model: 'storage_locations', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'storage_locations', 'location_type', { type: Sequelize.DataTypes.ENUM, values: ['zone','aisle','rack','shelf','bin','staging','receiving','shipping'], }, { transaction } ); await queryInterface.addColumn( 'storage_locations', 'is_active', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'storage_locations', 'notes', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'inventory_items', 'productId', { type: Sequelize.DataTypes.UUID, references: { model: 'products', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'inventory_items', 'storage_locationId', { type: Sequelize.DataTypes.UUID, references: { model: 'storage_locations', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'inventory_items', 'lot_number', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'inventory_items', 'serial_number', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'inventory_items', 'expiry_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'inventory_items', 'quantity_on_hand', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'inventory_items', 'quantity_reserved', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'inventory_items', 'quantity_available', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'inventory_items', 'last_counted_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'inventory_items', 'is_quarantined', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'inventory_items', 'quarantine_reason', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'stock_movements', 'reference_number', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'stock_movements', 'movement_type', { type: Sequelize.DataTypes.ENUM, values: ['receipt','issue','transfer','adjustment','return_in','return_out'], }, { transaction } ); await queryInterface.addColumn( 'stock_movements', 'status', { type: Sequelize.DataTypes.ENUM, values: ['draft','posted','cancelled'], }, { transaction } ); await queryInterface.addColumn( 'stock_movements', 'movement_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'stock_movements', 'warehouseId', { type: Sequelize.DataTypes.UUID, references: { model: 'warehouses', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_movements', 'supplierId', { type: Sequelize.DataTypes.UUID, references: { model: 'suppliers', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_movements', 'requested_byId', { type: Sequelize.DataTypes.UUID, references: { model: 'users', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_movements', 'approved_byId', { type: Sequelize.DataTypes.UUID, references: { model: 'users', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_movements', 'remarks', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'stock_movement_lines', 'stock_movementId', { type: Sequelize.DataTypes.UUID, references: { model: 'stock_movements', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_movement_lines', 'productId', { type: Sequelize.DataTypes.UUID, references: { model: 'products', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_movement_lines', 'from_locationId', { type: Sequelize.DataTypes.UUID, references: { model: 'storage_locations', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_movement_lines', 'to_locationId', { type: Sequelize.DataTypes.UUID, references: { model: 'storage_locations', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_movement_lines', 'quantity', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'stock_movement_lines', 'unit_cost', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'stock_movement_lines', 'lot_number', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'stock_movement_lines', 'serial_number', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'stock_movement_lines', 'expiry_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'stock_movement_lines', 'line_notes', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'stock_counts', 'count_number', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'stock_counts', 'status', { type: Sequelize.DataTypes.ENUM, values: ['planned','in_progress','completed','cancelled'], }, { transaction } ); await queryInterface.addColumn( 'stock_counts', 'warehouseId', { type: Sequelize.DataTypes.UUID, references: { model: 'warehouses', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_counts', 'storage_locationId', { type: Sequelize.DataTypes.UUID, references: { model: 'storage_locations', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_counts', 'scheduled_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'stock_counts', 'started_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'stock_counts', 'completed_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'stock_counts', 'created_by_userId', { type: Sequelize.DataTypes.UUID, references: { model: 'users', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_counts', 'verified_by_userId', { type: Sequelize.DataTypes.UUID, references: { model: 'users', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_counts', 'notes', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'stock_count_lines', 'stock_countId', { type: Sequelize.DataTypes.UUID, references: { model: 'stock_counts', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_count_lines', 'productId', { type: Sequelize.DataTypes.UUID, references: { model: 'products', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_count_lines', 'storage_locationId', { type: Sequelize.DataTypes.UUID, references: { model: 'storage_locations', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'stock_count_lines', 'lot_number', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'stock_count_lines', 'serial_number', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'stock_count_lines', 'system_quantity', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'stock_count_lines', 'counted_quantity', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'stock_count_lines', 'variance_quantity', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'stock_count_lines', 'reason', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'reorder_rules', 'productId', { type: Sequelize.DataTypes.UUID, references: { model: 'products', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'reorder_rules', 'warehouseId', { type: Sequelize.DataTypes.UUID, references: { model: 'warehouses', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'reorder_rules', 'storage_locationId', { type: Sequelize.DataTypes.UUID, references: { model: 'storage_locations', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'reorder_rules', 'min_quantity', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'reorder_rules', 'max_quantity', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'reorder_rules', 'reorder_point', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'reorder_rules', 'reorder_quantity', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'reorder_rules', 'lead_time_days', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'reorder_rules', 'is_active', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'alerts', 'alert_type', { type: Sequelize.DataTypes.ENUM, values: ['low_stock','expired_stock','near_expiry','quarantine','negative_stock'], }, { transaction } ); await queryInterface.addColumn( 'alerts', 'severity', { type: Sequelize.DataTypes.ENUM, values: ['info','warning','critical'], }, { transaction } ); await queryInterface.addColumn( 'alerts', 'productId', { type: Sequelize.DataTypes.UUID, references: { model: 'products', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'alerts', 'warehouseId', { type: Sequelize.DataTypes.UUID, references: { model: 'warehouses', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'alerts', 'storage_locationId', { type: Sequelize.DataTypes.UUID, references: { model: 'storage_locations', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'alerts', 'triggered_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'alerts', 'acknowledged_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'alerts', 'acknowledged_byId', { type: Sequelize.DataTypes.UUID, references: { model: 'users', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'alerts', 'is_resolved', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'alerts', 'resolved_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'alerts', 'message', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await transaction.commit(); } catch (err) { await transaction.rollback(); throw err; } }, /** * @param {QueryInterface} queryInterface * @param {Sequelize} Sequelize * @returns {Promise} */ async down(queryInterface, Sequelize) { /** * @type {Transaction} */ const transaction = await queryInterface.sequelize.transaction(); try { await queryInterface.removeColumn( 'alerts', 'message', { transaction } ); await queryInterface.removeColumn( 'alerts', 'resolved_at', { transaction } ); await queryInterface.removeColumn( 'alerts', 'is_resolved', { transaction } ); await queryInterface.removeColumn( 'alerts', 'acknowledged_byId', { transaction } ); await queryInterface.removeColumn( 'alerts', 'acknowledged_at', { transaction } ); await queryInterface.removeColumn( 'alerts', 'triggered_at', { transaction } ); await queryInterface.removeColumn( 'alerts', 'storage_locationId', { transaction } ); await queryInterface.removeColumn( 'alerts', 'warehouseId', { transaction } ); await queryInterface.removeColumn( 'alerts', 'productId', { transaction } ); await queryInterface.removeColumn( 'alerts', 'severity', { transaction } ); await queryInterface.removeColumn( 'alerts', 'alert_type', { transaction } ); await queryInterface.removeColumn( 'reorder_rules', 'is_active', { transaction } ); await queryInterface.removeColumn( 'reorder_rules', 'lead_time_days', { transaction } ); await queryInterface.removeColumn( 'reorder_rules', 'reorder_quantity', { transaction } ); await queryInterface.removeColumn( 'reorder_rules', 'reorder_point', { transaction } ); await queryInterface.removeColumn( 'reorder_rules', 'max_quantity', { transaction } ); await queryInterface.removeColumn( 'reorder_rules', 'min_quantity', { transaction } ); await queryInterface.removeColumn( 'reorder_rules', 'storage_locationId', { transaction } ); await queryInterface.removeColumn( 'reorder_rules', 'warehouseId', { transaction } ); await queryInterface.removeColumn( 'reorder_rules', 'productId', { transaction } ); await queryInterface.removeColumn( 'stock_count_lines', 'reason', { transaction } ); await queryInterface.removeColumn( 'stock_count_lines', 'variance_quantity', { transaction } ); await queryInterface.removeColumn( 'stock_count_lines', 'counted_quantity', { transaction } ); await queryInterface.removeColumn( 'stock_count_lines', 'system_quantity', { transaction } ); await queryInterface.removeColumn( 'stock_count_lines', 'serial_number', { transaction } ); await queryInterface.removeColumn( 'stock_count_lines', 'lot_number', { transaction } ); await queryInterface.removeColumn( 'stock_count_lines', 'storage_locationId', { transaction } ); await queryInterface.removeColumn( 'stock_count_lines', 'productId', { transaction } ); await queryInterface.removeColumn( 'stock_count_lines', 'stock_countId', { transaction } ); await queryInterface.removeColumn( 'stock_counts', 'notes', { transaction } ); await queryInterface.removeColumn( 'stock_counts', 'verified_by_userId', { transaction } ); await queryInterface.removeColumn( 'stock_counts', 'created_by_userId', { transaction } ); await queryInterface.removeColumn( 'stock_counts', 'completed_at', { transaction } ); await queryInterface.removeColumn( 'stock_counts', 'started_at', { transaction } ); await queryInterface.removeColumn( 'stock_counts', 'scheduled_at', { transaction } ); await queryInterface.removeColumn( 'stock_counts', 'storage_locationId', { transaction } ); await queryInterface.removeColumn( 'stock_counts', 'warehouseId', { transaction } ); await queryInterface.removeColumn( 'stock_counts', 'status', { transaction } ); await queryInterface.removeColumn( 'stock_counts', 'count_number', { transaction } ); await queryInterface.removeColumn( 'stock_movement_lines', 'line_notes', { transaction } ); await queryInterface.removeColumn( 'stock_movement_lines', 'expiry_at', { transaction } ); await queryInterface.removeColumn( 'stock_movement_lines', 'serial_number', { transaction } ); await queryInterface.removeColumn( 'stock_movement_lines', 'lot_number', { transaction } ); await queryInterface.removeColumn( 'stock_movement_lines', 'unit_cost', { transaction } ); await queryInterface.removeColumn( 'stock_movement_lines', 'quantity', { transaction } ); await queryInterface.removeColumn( 'stock_movement_lines', 'to_locationId', { transaction } ); await queryInterface.removeColumn( 'stock_movement_lines', 'from_locationId', { transaction } ); await queryInterface.removeColumn( 'stock_movement_lines', 'productId', { transaction } ); await queryInterface.removeColumn( 'stock_movement_lines', 'stock_movementId', { transaction } ); await queryInterface.removeColumn( 'stock_movements', 'remarks', { transaction } ); await queryInterface.removeColumn( 'stock_movements', 'approved_byId', { transaction } ); await queryInterface.removeColumn( 'stock_movements', 'requested_byId', { transaction } ); await queryInterface.removeColumn( 'stock_movements', 'supplierId', { transaction } ); await queryInterface.removeColumn( 'stock_movements', 'warehouseId', { transaction } ); await queryInterface.removeColumn( 'stock_movements', 'movement_at', { transaction } ); await queryInterface.removeColumn( 'stock_movements', 'status', { transaction } ); await queryInterface.removeColumn( 'stock_movements', 'movement_type', { transaction } ); await queryInterface.removeColumn( 'stock_movements', 'reference_number', { transaction } ); await queryInterface.removeColumn( 'inventory_items', 'quarantine_reason', { transaction } ); await queryInterface.removeColumn( 'inventory_items', 'is_quarantined', { transaction } ); await queryInterface.removeColumn( 'inventory_items', 'last_counted_at', { transaction } ); await queryInterface.removeColumn( 'inventory_items', 'quantity_available', { transaction } ); await queryInterface.removeColumn( 'inventory_items', 'quantity_reserved', { transaction } ); await queryInterface.removeColumn( 'inventory_items', 'quantity_on_hand', { transaction } ); await queryInterface.removeColumn( 'inventory_items', 'expiry_at', { transaction } ); await queryInterface.removeColumn( 'inventory_items', 'serial_number', { transaction } ); await queryInterface.removeColumn( 'inventory_items', 'lot_number', { transaction } ); await queryInterface.removeColumn( 'inventory_items', 'storage_locationId', { transaction } ); await queryInterface.removeColumn( 'inventory_items', 'productId', { transaction } ); await queryInterface.removeColumn( 'storage_locations', 'notes', { transaction } ); await queryInterface.removeColumn( 'storage_locations', 'is_active', { transaction } ); await queryInterface.removeColumn( 'storage_locations', 'location_type', { transaction } ); await queryInterface.removeColumn( 'storage_locations', 'parent_locationId', { transaction } ); await queryInterface.removeColumn( 'storage_locations', 'warehouseId', { transaction } ); await queryInterface.removeColumn( 'storage_locations', 'code', { transaction } ); await queryInterface.removeColumn( 'storage_locations', 'name', { transaction } ); await queryInterface.removeColumn( 'warehouses', 'notes', { transaction } ); await queryInterface.removeColumn( 'warehouses', 'is_active', { transaction } ); await queryInterface.removeColumn( 'warehouses', 'address', { transaction } ); await queryInterface.removeColumn( 'warehouses', 'code', { transaction } ); await queryInterface.removeColumn( 'warehouses', 'name', { transaction } ); await queryInterface.removeColumn( 'products', 'description', { transaction } ); await queryInterface.removeColumn( 'products', 'is_active', { transaction } ); await queryInterface.removeColumn( 'products', 'is_serialized', { transaction } ); await queryInterface.removeColumn( 'products', 'lead_time_days', { transaction } ); await queryInterface.removeColumn( 'products', 'reorder_quantity', { transaction } ); await queryInterface.removeColumn( 'products', 'reorder_point', { transaction } ); await queryInterface.removeColumn( 'products', 'sale_price', { transaction } ); await queryInterface.removeColumn( 'products', 'cost_price', { transaction } ); await queryInterface.removeColumn( 'products', 'default_supplierId', { transaction } ); await queryInterface.removeColumn( 'products', 'unitId', { transaction } ); await queryInterface.removeColumn( 'products', 'categoryId', { transaction } ); await queryInterface.removeColumn( 'products', 'barcode', { transaction } ); await queryInterface.removeColumn( 'products', 'sku', { transaction } ); await queryInterface.removeColumn( 'products', 'name', { transaction } ); await queryInterface.removeColumn( 'units', 'is_active', { transaction } ); await queryInterface.removeColumn( 'units', 'precision', { transaction } ); await queryInterface.removeColumn( 'units', 'symbol', { transaction } ); await queryInterface.removeColumn( 'units', 'name', { transaction } ); await queryInterface.removeColumn( 'categories', 'is_active', { transaction } ); await queryInterface.removeColumn( 'categories', 'parent_categoryId', { transaction } ); await queryInterface.removeColumn( 'categories', 'description', { transaction } ); await queryInterface.removeColumn( 'categories', 'code', { transaction } ); await queryInterface.removeColumn( 'categories', 'name', { transaction } ); await queryInterface.removeColumn( 'suppliers', 'notes', { transaction } ); await queryInterface.removeColumn( 'suppliers', 'is_active', { transaction } ); await queryInterface.removeColumn( 'suppliers', 'tax_number', { transaction } ); await queryInterface.removeColumn( 'suppliers', 'address', { transaction } ); await queryInterface.removeColumn( 'suppliers', 'phone', { transaction } ); await queryInterface.removeColumn( 'suppliers', 'email', { transaction } ); await queryInterface.removeColumn( 'suppliers', 'name', { transaction } ); await queryInterface.removeColumn( 'permissions', 'name', { transaction } ); await queryInterface.removeColumn( 'roles', 'role_customization', { transaction } ); await queryInterface.removeColumn( 'roles', 'name', { transaction } ); await queryInterface.removeColumn( 'users', 'app_roleId', { transaction } ); await queryInterface.removeColumn( 'users', 'provider', { transaction } ); await queryInterface.removeColumn( 'users', 'passwordResetTokenExpiresAt', { transaction } ); await queryInterface.removeColumn( 'users', 'passwordResetToken', { transaction } ); await queryInterface.removeColumn( 'users', 'emailVerificationTokenExpiresAt', { transaction } ); await queryInterface.removeColumn( 'users', 'emailVerificationToken', { transaction } ); await queryInterface.removeColumn( 'users', 'emailVerified', { transaction } ); await queryInterface.removeColumn( 'users', 'password', { transaction } ); await queryInterface.removeColumn( 'users', 'disabled', { transaction } ); await queryInterface.removeColumn( 'users', 'email', { transaction } ); await queryInterface.removeColumn( 'users', 'phoneNumber', { transaction } ); await queryInterface.removeColumn( 'users', 'lastName', { transaction } ); await queryInterface.removeColumn( 'users', 'firstName', { transaction } ); await queryInterface.dropTable('alerts', { transaction }); await queryInterface.dropTable('reorder_rules', { transaction }); await queryInterface.dropTable('stock_count_lines', { transaction }); await queryInterface.dropTable('stock_counts', { transaction }); await queryInterface.dropTable('stock_movement_lines', { transaction }); await queryInterface.dropTable('stock_movements', { transaction }); await queryInterface.dropTable('inventory_items', { transaction }); await queryInterface.dropTable('storage_locations', { transaction }); await queryInterface.dropTable('warehouses', { transaction }); await queryInterface.dropTable('products', { transaction }); await queryInterface.dropTable('units', { transaction }); await queryInterface.dropTable('categories', { transaction }); await queryInterface.dropTable('suppliers', { transaction }); await queryInterface.dropTable('permissions', { transaction }); await queryInterface.dropTable('roles', { transaction }); await queryInterface.dropTable('users', { transaction }); await transaction.commit(); } catch (err) { await transaction.rollback(); throw err; } } };