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('salons', { 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('staff_members', { 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('services', { 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('staff_service_assignments', { 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('working_hour_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('time_off_blocks', { 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('appointments', { 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('payments', { 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('notifications', { 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('salon_settings', { 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( 'salons', 'name', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salons', 'slug', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salons', 'phone', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salons', 'email', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salons', 'address_line1', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salons', 'address_line2', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salons', 'city', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salons', 'state', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salons', 'postal_code', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salons', 'country', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salons', 'latitude', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'salons', 'longitude', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'salons', 'timezone', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salons', 'website_url', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salons', 'is_active', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'salons', 'description', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'staff_members', 'userId', { type: Sequelize.DataTypes.UUID, references: { model: 'users', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'staff_members', 'salonId', { type: Sequelize.DataTypes.UUID, references: { model: 'salons', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'staff_members', 'display_name', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'staff_members', 'job_title', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'staff_members', 'bio', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'staff_members', 'buffer_minutes_before', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'staff_members', 'buffer_minutes_after', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'staff_members', 'is_bookable', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'staff_members', 'is_active', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'staff_members', 'sort_order', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'services', 'salonId', { type: Sequelize.DataTypes.UUID, references: { model: 'salons', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'services', 'name', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'services', 'description', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'services', 'duration_minutes', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'services', 'price', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'services', 'pricing_type', { type: Sequelize.DataTypes.ENUM, values: ['fixed','from','free'], }, { transaction } ); await queryInterface.addColumn( 'services', 'requires_deposit', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'services', 'deposit_amount', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'services', 'is_active', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'staff_service_assignments', 'staff_memberId', { type: Sequelize.DataTypes.UUID, references: { model: 'staff_members', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'staff_service_assignments', 'serviceId', { type: Sequelize.DataTypes.UUID, references: { model: 'services', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'staff_service_assignments', 'duration_override_minutes', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'staff_service_assignments', 'price_override', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'staff_service_assignments', 'is_active', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'working_hour_rules', 'salonId', { type: Sequelize.DataTypes.UUID, references: { model: 'salons', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'working_hour_rules', 'staff_memberId', { type: Sequelize.DataTypes.UUID, references: { model: 'staff_members', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'working_hour_rules', 'day_of_week', { type: Sequelize.DataTypes.ENUM, values: ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'], }, { transaction } ); await queryInterface.addColumn( 'working_hour_rules', 'start_time_local', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'working_hour_rules', 'end_time_local', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'working_hour_rules', 'is_closed', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'working_hour_rules', 'label', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'time_off_blocks', 'salonId', { type: Sequelize.DataTypes.UUID, references: { model: 'salons', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'time_off_blocks', 'staff_memberId', { type: Sequelize.DataTypes.UUID, references: { model: 'staff_members', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'time_off_blocks', 'title', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'time_off_blocks', 'starts_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'time_off_blocks', 'ends_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'time_off_blocks', 'all_day', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'time_off_blocks', 'reason', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'time_off_blocks', 'status', { type: Sequelize.DataTypes.ENUM, values: ['planned','approved','cancelled'], }, { transaction } ); await queryInterface.addColumn( 'appointments', 'salonId', { type: Sequelize.DataTypes.UUID, references: { model: 'salons', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'clientId', { type: Sequelize.DataTypes.UUID, references: { model: 'users', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'staff_memberId', { type: Sequelize.DataTypes.UUID, references: { model: 'staff_members', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'serviceId', { type: Sequelize.DataTypes.UUID, references: { model: 'services', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'starts_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'ends_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'status', { type: Sequelize.DataTypes.ENUM, values: ['requested','confirmed','checked_in','completed','cancelled','no_show'], }, { transaction } ); await queryInterface.addColumn( 'appointments', 'booking_source', { type: Sequelize.DataTypes.ENUM, values: ['online','phone','walk_in','staff'], }, { transaction } ); await queryInterface.addColumn( 'appointments', 'service_price', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'deposit_amount', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'deposit_paid', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'client_notes', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'internal_notes', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'cancellation_reason', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'confirmed_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'appointments', 'cancelled_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'payments', 'appointmentId', { type: Sequelize.DataTypes.UUID, references: { model: 'appointments', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'payments', 'payerId', { type: Sequelize.DataTypes.UUID, references: { model: 'users', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'payments', 'amount', { type: Sequelize.DataTypes.DECIMAL, }, { transaction } ); await queryInterface.addColumn( 'payments', 'currency', { type: Sequelize.DataTypes.ENUM, values: ['USD','EUR','GBP','CAD','AUD'], }, { transaction } ); await queryInterface.addColumn( 'payments', 'status', { type: Sequelize.DataTypes.ENUM, values: ['pending','authorized','paid','refunded','failed','cancelled'], }, { transaction } ); await queryInterface.addColumn( 'payments', 'method', { type: Sequelize.DataTypes.ENUM, values: ['cash','card','online','gift_card','bank_transfer'], }, { transaction } ); await queryInterface.addColumn( 'payments', 'provider', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'payments', 'provider_reference', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'payments', 'paid_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'payments', 'refunded_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'payments', 'notes', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'notifications', 'recipientId', { type: Sequelize.DataTypes.UUID, references: { model: 'users', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'notifications', 'appointmentId', { type: Sequelize.DataTypes.UUID, references: { model: 'appointments', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'notifications', 'channel', { type: Sequelize.DataTypes.ENUM, values: ['email','sms','push'], }, { transaction } ); await queryInterface.addColumn( 'notifications', 'template_key', { type: Sequelize.DataTypes.ENUM, values: ['appointment_requested','appointment_confirmed','appointment_cancelled','appointment_reminder','payment_receipt'], }, { transaction } ); await queryInterface.addColumn( 'notifications', 'subject', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'notifications', 'message', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'notifications', 'status', { type: Sequelize.DataTypes.ENUM, values: ['queued','sent','failed'], }, { transaction } ); await queryInterface.addColumn( 'notifications', 'scheduled_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'notifications', 'sent_at', { type: Sequelize.DataTypes.DATE, }, { transaction } ); await queryInterface.addColumn( 'notifications', 'failure_reason', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salon_settings', 'salonId', { type: Sequelize.DataTypes.UUID, references: { model: 'salons', key: 'id', }, }, { transaction } ); await queryInterface.addColumn( 'salon_settings', 'currency_code', { type: Sequelize.DataTypes.TEXT, }, { transaction } ); await queryInterface.addColumn( 'salon_settings', 'booking_lead_time_minutes', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'salon_settings', 'booking_horizon_days', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'salon_settings', 'slot_interval_minutes', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'salon_settings', 'allow_client_cancellation', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'salon_settings', 'cancellation_cutoff_minutes', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'salon_settings', 'require_staff_confirmation', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'salon_settings', 'send_reminders', { type: Sequelize.DataTypes.BOOLEAN, defaultValue: false, allowNull: false, }, { transaction } ); await queryInterface.addColumn( 'salon_settings', 'reminder_minutes_before', { type: Sequelize.DataTypes.INTEGER, }, { transaction } ); await queryInterface.addColumn( 'salon_settings', 'policy_text', { 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( 'salon_settings', 'policy_text', { transaction } ); await queryInterface.removeColumn( 'salon_settings', 'reminder_minutes_before', { transaction } ); await queryInterface.removeColumn( 'salon_settings', 'send_reminders', { transaction } ); await queryInterface.removeColumn( 'salon_settings', 'require_staff_confirmation', { transaction } ); await queryInterface.removeColumn( 'salon_settings', 'cancellation_cutoff_minutes', { transaction } ); await queryInterface.removeColumn( 'salon_settings', 'allow_client_cancellation', { transaction } ); await queryInterface.removeColumn( 'salon_settings', 'slot_interval_minutes', { transaction } ); await queryInterface.removeColumn( 'salon_settings', 'booking_horizon_days', { transaction } ); await queryInterface.removeColumn( 'salon_settings', 'booking_lead_time_minutes', { transaction } ); await queryInterface.removeColumn( 'salon_settings', 'currency_code', { transaction } ); await queryInterface.removeColumn( 'salon_settings', 'salonId', { transaction } ); await queryInterface.removeColumn( 'notifications', 'failure_reason', { transaction } ); await queryInterface.removeColumn( 'notifications', 'sent_at', { transaction } ); await queryInterface.removeColumn( 'notifications', 'scheduled_at', { transaction } ); await queryInterface.removeColumn( 'notifications', 'status', { transaction } ); await queryInterface.removeColumn( 'notifications', 'message', { transaction } ); await queryInterface.removeColumn( 'notifications', 'subject', { transaction } ); await queryInterface.removeColumn( 'notifications', 'template_key', { transaction } ); await queryInterface.removeColumn( 'notifications', 'channel', { transaction } ); await queryInterface.removeColumn( 'notifications', 'appointmentId', { transaction } ); await queryInterface.removeColumn( 'notifications', 'recipientId', { transaction } ); await queryInterface.removeColumn( 'payments', 'notes', { transaction } ); await queryInterface.removeColumn( 'payments', 'refunded_at', { transaction } ); await queryInterface.removeColumn( 'payments', 'paid_at', { transaction } ); await queryInterface.removeColumn( 'payments', 'provider_reference', { transaction } ); await queryInterface.removeColumn( 'payments', 'provider', { transaction } ); await queryInterface.removeColumn( 'payments', 'method', { transaction } ); await queryInterface.removeColumn( 'payments', 'status', { transaction } ); await queryInterface.removeColumn( 'payments', 'currency', { transaction } ); await queryInterface.removeColumn( 'payments', 'amount', { transaction } ); await queryInterface.removeColumn( 'payments', 'payerId', { transaction } ); await queryInterface.removeColumn( 'payments', 'appointmentId', { transaction } ); await queryInterface.removeColumn( 'appointments', 'cancelled_at', { transaction } ); await queryInterface.removeColumn( 'appointments', 'confirmed_at', { transaction } ); await queryInterface.removeColumn( 'appointments', 'cancellation_reason', { transaction } ); await queryInterface.removeColumn( 'appointments', 'internal_notes', { transaction } ); await queryInterface.removeColumn( 'appointments', 'client_notes', { transaction } ); await queryInterface.removeColumn( 'appointments', 'deposit_paid', { transaction } ); await queryInterface.removeColumn( 'appointments', 'deposit_amount', { transaction } ); await queryInterface.removeColumn( 'appointments', 'service_price', { transaction } ); await queryInterface.removeColumn( 'appointments', 'booking_source', { transaction } ); await queryInterface.removeColumn( 'appointments', 'status', { transaction } ); await queryInterface.removeColumn( 'appointments', 'ends_at', { transaction } ); await queryInterface.removeColumn( 'appointments', 'starts_at', { transaction } ); await queryInterface.removeColumn( 'appointments', 'serviceId', { transaction } ); await queryInterface.removeColumn( 'appointments', 'staff_memberId', { transaction } ); await queryInterface.removeColumn( 'appointments', 'clientId', { transaction } ); await queryInterface.removeColumn( 'appointments', 'salonId', { transaction } ); await queryInterface.removeColumn( 'time_off_blocks', 'status', { transaction } ); await queryInterface.removeColumn( 'time_off_blocks', 'reason', { transaction } ); await queryInterface.removeColumn( 'time_off_blocks', 'all_day', { transaction } ); await queryInterface.removeColumn( 'time_off_blocks', 'ends_at', { transaction } ); await queryInterface.removeColumn( 'time_off_blocks', 'starts_at', { transaction } ); await queryInterface.removeColumn( 'time_off_blocks', 'title', { transaction } ); await queryInterface.removeColumn( 'time_off_blocks', 'staff_memberId', { transaction } ); await queryInterface.removeColumn( 'time_off_blocks', 'salonId', { transaction } ); await queryInterface.removeColumn( 'working_hour_rules', 'label', { transaction } ); await queryInterface.removeColumn( 'working_hour_rules', 'is_closed', { transaction } ); await queryInterface.removeColumn( 'working_hour_rules', 'end_time_local', { transaction } ); await queryInterface.removeColumn( 'working_hour_rules', 'start_time_local', { transaction } ); await queryInterface.removeColumn( 'working_hour_rules', 'day_of_week', { transaction } ); await queryInterface.removeColumn( 'working_hour_rules', 'staff_memberId', { transaction } ); await queryInterface.removeColumn( 'working_hour_rules', 'salonId', { transaction } ); await queryInterface.removeColumn( 'staff_service_assignments', 'is_active', { transaction } ); await queryInterface.removeColumn( 'staff_service_assignments', 'price_override', { transaction } ); await queryInterface.removeColumn( 'staff_service_assignments', 'duration_override_minutes', { transaction } ); await queryInterface.removeColumn( 'staff_service_assignments', 'serviceId', { transaction } ); await queryInterface.removeColumn( 'staff_service_assignments', 'staff_memberId', { transaction } ); await queryInterface.removeColumn( 'services', 'is_active', { transaction } ); await queryInterface.removeColumn( 'services', 'deposit_amount', { transaction } ); await queryInterface.removeColumn( 'services', 'requires_deposit', { transaction } ); await queryInterface.removeColumn( 'services', 'pricing_type', { transaction } ); await queryInterface.removeColumn( 'services', 'price', { transaction } ); await queryInterface.removeColumn( 'services', 'duration_minutes', { transaction } ); await queryInterface.removeColumn( 'services', 'description', { transaction } ); await queryInterface.removeColumn( 'services', 'name', { transaction } ); await queryInterface.removeColumn( 'services', 'salonId', { transaction } ); await queryInterface.removeColumn( 'staff_members', 'sort_order', { transaction } ); await queryInterface.removeColumn( 'staff_members', 'is_active', { transaction } ); await queryInterface.removeColumn( 'staff_members', 'is_bookable', { transaction } ); await queryInterface.removeColumn( 'staff_members', 'buffer_minutes_after', { transaction } ); await queryInterface.removeColumn( 'staff_members', 'buffer_minutes_before', { transaction } ); await queryInterface.removeColumn( 'staff_members', 'bio', { transaction } ); await queryInterface.removeColumn( 'staff_members', 'job_title', { transaction } ); await queryInterface.removeColumn( 'staff_members', 'display_name', { transaction } ); await queryInterface.removeColumn( 'staff_members', 'salonId', { transaction } ); await queryInterface.removeColumn( 'staff_members', 'userId', { transaction } ); await queryInterface.removeColumn( 'salons', 'description', { transaction } ); await queryInterface.removeColumn( 'salons', 'is_active', { transaction } ); await queryInterface.removeColumn( 'salons', 'website_url', { transaction } ); await queryInterface.removeColumn( 'salons', 'timezone', { transaction } ); await queryInterface.removeColumn( 'salons', 'longitude', { transaction } ); await queryInterface.removeColumn( 'salons', 'latitude', { transaction } ); await queryInterface.removeColumn( 'salons', 'country', { transaction } ); await queryInterface.removeColumn( 'salons', 'postal_code', { transaction } ); await queryInterface.removeColumn( 'salons', 'state', { transaction } ); await queryInterface.removeColumn( 'salons', 'city', { transaction } ); await queryInterface.removeColumn( 'salons', 'address_line2', { transaction } ); await queryInterface.removeColumn( 'salons', 'address_line1', { transaction } ); await queryInterface.removeColumn( 'salons', 'email', { transaction } ); await queryInterface.removeColumn( 'salons', 'phone', { transaction } ); await queryInterface.removeColumn( 'salons', 'slug', { transaction } ); await queryInterface.removeColumn( 'salons', '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('salon_settings', { transaction }); await queryInterface.dropTable('notifications', { transaction }); await queryInterface.dropTable('payments', { transaction }); await queryInterface.dropTable('appointments', { transaction }); await queryInterface.dropTable('time_off_blocks', { transaction }); await queryInterface.dropTable('working_hour_rules', { transaction }); await queryInterface.dropTable('staff_service_assignments', { transaction }); await queryInterface.dropTable('services', { transaction }); await queryInterface.dropTable('staff_members', { transaction }); await queryInterface.dropTable('salons', { 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; } } };