38896-vm/backend/src/db/migrations/1772329245686.js
2026-03-01 01:42:01 +00:00

5904 lines
185 KiB
JavaScript

module.exports = {
/**
* @param {QueryInterface} queryInterface
* @param {Sequelize} Sequelize
* @returns {Promise<void>}
*/
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('organizations', {
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('merchant_profiles', {
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('user_sessions', {
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('budgets', {
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('transactions', {
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('recurring_transaction_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('tasks', {
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('reports', {
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('scheduled_reports', {
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('activity_logs', {
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('user_preferences', {
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('exchange_rates', {
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('ai_insights', {
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('support_conversations', {
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('support_messages', {
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(
'users',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
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(
'roles',
'globalAccess',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'permissions',
'name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'organizations',
'name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'display_name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'legal_name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'business_email',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'business_phone',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'tax_number',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'address_line1',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'address_line2',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'city',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'state',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'postal_code',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'country',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'timezone',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'default_currency',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'merchant_profiles',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'user_sessions',
'userId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'user_sessions',
'device_name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'user_sessions',
'device_platform',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'user_sessions',
'ip_address',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'user_sessions',
'user_agent',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'user_sessions',
'refresh_token_hash',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'user_sessions',
'last_seen_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'user_sessions',
'expires_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'user_sessions',
'revoked',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'user_sessions',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'categories',
'merchant_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'merchant_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'categories',
'name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'categories',
'kind',
{
type: Sequelize.DataTypes.ENUM,
values: ['income','expense','transfer','other'],
},
{ transaction }
);
await queryInterface.addColumn(
'categories',
'parent_categoryId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'categories',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'categories',
'color_hex',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'categories',
'icon_key',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'categories',
'is_active',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'categories',
'is_system',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'categories',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'userId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'merchant_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'merchant_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'description',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'period',
{
type: Sequelize.DataTypes.ENUM,
values: ['weekly','monthly','quarterly','yearly','custom'],
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'start_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'end_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'amount_limit',
{
type: Sequelize.DataTypes.DECIMAL,
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'currency',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'status',
{
type: Sequelize.DataTypes.ENUM,
values: ['active','paused','completed','archived'],
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'alert_on_threshold',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'alert_threshold_percent',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'alert_on_exceed',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'budgets',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'merchant_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'merchant_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'userId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'budgetId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'budgets',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'categoryId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'categories',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'type',
{
type: Sequelize.DataTypes.ENUM,
values: ['income','expense','payment','refund','transfer','adjustment'],
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'status',
{
type: Sequelize.DataTypes.ENUM,
values: ['pending','cleared','reconciled','voided'],
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'amount',
{
type: Sequelize.DataTypes.DECIMAL,
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'currency',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'transaction_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'counterparty_name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'reference_code',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'description',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'flagged',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'source',
{
type: Sequelize.DataTypes.ENUM,
values: ['manual','import','api','ai_categorized'],
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'tax_amount',
{
type: Sequelize.DataTypes.DECIMAL,
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'fee_amount',
{
type: Sequelize.DataTypes.DECIMAL,
},
{ transaction }
);
await queryInterface.addColumn(
'transactions',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'merchant_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'merchant_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'userId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'categoryId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'categories',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'budgetId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'budgets',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'type',
{
type: Sequelize.DataTypes.ENUM,
values: ['income','expense','payment','refund','transfer'],
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'amount',
{
type: Sequelize.DataTypes.DECIMAL,
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'currency',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'frequency',
{
type: Sequelize.DataTypes.ENUM,
values: ['daily','weekly','monthly','quarterly','yearly'],
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'interval_count',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'start_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'end_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'next_run_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'active',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'notes',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'recurring_transaction_rules',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'userId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'merchant_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'merchant_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'title',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'description',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'priority',
{
type: Sequelize.DataTypes.ENUM,
values: ['low','medium','high','urgent'],
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'status',
{
type: Sequelize.DataTypes.ENUM,
values: ['pending','in_progress','completed','cancelled'],
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'due_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'remind_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'completed_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'recurring',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'recurrence_pattern',
{
type: Sequelize.DataTypes.ENUM,
values: ['daily','weekly','monthly','quarterly','yearly','custom'],
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'recurrence_interval',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'calendar_event_external_key',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'timezone',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'tasks',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'reports',
'merchant_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'merchant_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'reports',
'userId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'reports',
'name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'reports',
'type',
{
type: Sequelize.DataTypes.ENUM,
values: ['cash_flow','profit_and_loss','category_spend','monthly_summary','budget_performance','tax_summary'],
},
{ transaction }
);
await queryInterface.addColumn(
'reports',
'status',
{
type: Sequelize.DataTypes.ENUM,
values: ['draft','queued','processing','ready','failed'],
},
{ transaction }
);
await queryInterface.addColumn(
'reports',
'period_start_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'reports',
'period_end_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'reports',
'filters_json',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'reports',
'generated_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'reports',
'error_message',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'reports',
'include_ai_insights',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'reports',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'merchant_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'merchant_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'userId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'report_type',
{
type: Sequelize.DataTypes.ENUM,
values: ['cash_flow','profit_and_loss','category_spend','monthly_summary','budget_performance','tax_summary'],
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'schedule_frequency',
{
type: Sequelize.DataTypes.ENUM,
values: ['weekly','monthly','quarterly'],
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'day_of_week',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'day_of_month',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'next_run_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'active',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'export_format',
{
type: Sequelize.DataTypes.ENUM,
values: ['csv','pdf','both'],
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'recipients',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'filters_json',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'scheduled_reports',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'notifications',
'userId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'notifications',
'merchant_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'merchant_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'notifications',
'channel',
{
type: Sequelize.DataTypes.ENUM,
values: ['in_app','email','push','sms'],
},
{ transaction }
);
await queryInterface.addColumn(
'notifications',
'type',
{
type: Sequelize.DataTypes.ENUM,
values: ['budget_threshold','budget_exceeded','task_reminder','report_ready','security','system','chat_message'],
},
{ transaction }
);
await queryInterface.addColumn(
'notifications',
'title',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'notifications',
'message',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'notifications',
'action_url',
{
type: Sequelize.DataTypes.TEXT,
},
{ 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',
'read_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'notifications',
'status',
{
type: Sequelize.DataTypes.ENUM,
values: ['queued','sent','delivered','failed','read'],
},
{ transaction }
);
await queryInterface.addColumn(
'notifications',
'metadata_json',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'notifications',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'activity_logs',
'userId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'activity_logs',
'merchant_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'merchant_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'activity_logs',
'action',
{
type: Sequelize.DataTypes.ENUM,
values: ['create','update','delete','login','logout','export','import','approve','reject','view'],
},
{ transaction }
);
await queryInterface.addColumn(
'activity_logs',
'entity_name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'activity_logs',
'entity_key',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'activity_logs',
'summary',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'activity_logs',
'ip_address',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'activity_logs',
'user_agent',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'activity_logs',
'occurred_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'activity_logs',
'risk_level',
{
type: Sequelize.DataTypes.ENUM,
values: ['low','medium','high'],
},
{ transaction }
);
await queryInterface.addColumn(
'activity_logs',
'diff_json',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'activity_logs',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'userId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'locale',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'timezone',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'date_format',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'number_format',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'default_currency',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'dark_mode',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'email_notifications_enabled',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'push_notifications_enabled',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'budget_alerts_enabled',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'task_reminders_enabled',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'dashboard_layout_json',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'user_preferences',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'exchange_rates',
'base_currency',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'exchange_rates',
'quote_currency',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'exchange_rates',
'rate',
{
type: Sequelize.DataTypes.DECIMAL,
},
{ transaction }
);
await queryInterface.addColumn(
'exchange_rates',
'effective_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'exchange_rates',
'provider',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'exchange_rates',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'ai_insights',
'merchant_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'merchant_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'ai_insights',
'userId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'ai_insights',
'type',
{
type: Sequelize.DataTypes.ENUM,
values: ['overspending_risk','savings_opportunity','cash_flow_forecast','anomaly_detection','category_trend','budget_recommendation'],
},
{ transaction }
);
await queryInterface.addColumn(
'ai_insights',
'title',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_insights',
'summary',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_insights',
'model_name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_insights',
'confidence',
{
type: Sequelize.DataTypes.DECIMAL,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_insights',
'period_start_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_insights',
'period_end_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_insights',
'evidence_json',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_insights',
'generated_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_insights',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'support_conversations',
'merchant_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'merchant_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'support_conversations',
'opened_byId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'support_conversations',
'subject',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'support_conversations',
'status',
{
type: Sequelize.DataTypes.ENUM,
values: ['open','pending','resolved','closed'],
},
{ transaction }
);
await queryInterface.addColumn(
'support_conversations',
'priority',
{
type: Sequelize.DataTypes.ENUM,
values: ['low','medium','high','urgent'],
},
{ transaction }
);
await queryInterface.addColumn(
'support_conversations',
'last_message_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'support_conversations',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'support_messages',
'conversationId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'support_conversations',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'support_messages',
'senderId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'support_messages',
'message',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'support_messages',
'sent_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'support_messages',
'organizationsId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'organizations',
key: 'id',
},
},
{ transaction }
);
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
},
/**
* @param {QueryInterface} queryInterface
* @param {Sequelize} Sequelize
* @returns {Promise<void>}
*/
async down(queryInterface, Sequelize) {
/**
* @type {Transaction}
*/
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.removeColumn(
'support_messages',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'support_messages',
'sent_at',
{ transaction }
);
await queryInterface.removeColumn(
'support_messages',
'message',
{ transaction }
);
await queryInterface.removeColumn(
'support_messages',
'senderId',
{ transaction }
);
await queryInterface.removeColumn(
'support_messages',
'conversationId',
{ transaction }
);
await queryInterface.removeColumn(
'support_conversations',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'support_conversations',
'last_message_at',
{ transaction }
);
await queryInterface.removeColumn(
'support_conversations',
'priority',
{ transaction }
);
await queryInterface.removeColumn(
'support_conversations',
'status',
{ transaction }
);
await queryInterface.removeColumn(
'support_conversations',
'subject',
{ transaction }
);
await queryInterface.removeColumn(
'support_conversations',
'opened_byId',
{ transaction }
);
await queryInterface.removeColumn(
'support_conversations',
'merchant_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'ai_insights',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'ai_insights',
'generated_at',
{ transaction }
);
await queryInterface.removeColumn(
'ai_insights',
'evidence_json',
{ transaction }
);
await queryInterface.removeColumn(
'ai_insights',
'period_end_at',
{ transaction }
);
await queryInterface.removeColumn(
'ai_insights',
'period_start_at',
{ transaction }
);
await queryInterface.removeColumn(
'ai_insights',
'confidence',
{ transaction }
);
await queryInterface.removeColumn(
'ai_insights',
'model_name',
{ transaction }
);
await queryInterface.removeColumn(
'ai_insights',
'summary',
{ transaction }
);
await queryInterface.removeColumn(
'ai_insights',
'title',
{ transaction }
);
await queryInterface.removeColumn(
'ai_insights',
'type',
{ transaction }
);
await queryInterface.removeColumn(
'ai_insights',
'userId',
{ transaction }
);
await queryInterface.removeColumn(
'ai_insights',
'merchant_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'exchange_rates',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'exchange_rates',
'provider',
{ transaction }
);
await queryInterface.removeColumn(
'exchange_rates',
'effective_at',
{ transaction }
);
await queryInterface.removeColumn(
'exchange_rates',
'rate',
{ transaction }
);
await queryInterface.removeColumn(
'exchange_rates',
'quote_currency',
{ transaction }
);
await queryInterface.removeColumn(
'exchange_rates',
'base_currency',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'dashboard_layout_json',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'task_reminders_enabled',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'budget_alerts_enabled',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'push_notifications_enabled',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'email_notifications_enabled',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'dark_mode',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'default_currency',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'number_format',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'date_format',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'timezone',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'locale',
{ transaction }
);
await queryInterface.removeColumn(
'user_preferences',
'userId',
{ transaction }
);
await queryInterface.removeColumn(
'activity_logs',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'activity_logs',
'diff_json',
{ transaction }
);
await queryInterface.removeColumn(
'activity_logs',
'risk_level',
{ transaction }
);
await queryInterface.removeColumn(
'activity_logs',
'occurred_at',
{ transaction }
);
await queryInterface.removeColumn(
'activity_logs',
'user_agent',
{ transaction }
);
await queryInterface.removeColumn(
'activity_logs',
'ip_address',
{ transaction }
);
await queryInterface.removeColumn(
'activity_logs',
'summary',
{ transaction }
);
await queryInterface.removeColumn(
'activity_logs',
'entity_key',
{ transaction }
);
await queryInterface.removeColumn(
'activity_logs',
'entity_name',
{ transaction }
);
await queryInterface.removeColumn(
'activity_logs',
'action',
{ transaction }
);
await queryInterface.removeColumn(
'activity_logs',
'merchant_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'activity_logs',
'userId',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'metadata_json',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'status',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'read_at',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'sent_at',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'scheduled_at',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'action_url',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'message',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'title',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'type',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'channel',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'merchant_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'notifications',
'userId',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'filters_json',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'recipients',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'export_format',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'active',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'next_run_at',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'day_of_month',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'day_of_week',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'schedule_frequency',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'report_type',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'name',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'userId',
{ transaction }
);
await queryInterface.removeColumn(
'scheduled_reports',
'merchant_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'reports',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'reports',
'include_ai_insights',
{ transaction }
);
await queryInterface.removeColumn(
'reports',
'error_message',
{ transaction }
);
await queryInterface.removeColumn(
'reports',
'generated_at',
{ transaction }
);
await queryInterface.removeColumn(
'reports',
'filters_json',
{ transaction }
);
await queryInterface.removeColumn(
'reports',
'period_end_at',
{ transaction }
);
await queryInterface.removeColumn(
'reports',
'period_start_at',
{ transaction }
);
await queryInterface.removeColumn(
'reports',
'status',
{ transaction }
);
await queryInterface.removeColumn(
'reports',
'type',
{ transaction }
);
await queryInterface.removeColumn(
'reports',
'name',
{ transaction }
);
await queryInterface.removeColumn(
'reports',
'userId',
{ transaction }
);
await queryInterface.removeColumn(
'reports',
'merchant_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'timezone',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'calendar_event_external_key',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'recurrence_interval',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'recurrence_pattern',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'recurring',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'completed_at',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'remind_at',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'due_at',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'status',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'priority',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'description',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'title',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'merchant_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'tasks',
'userId',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'notes',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'active',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'next_run_at',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'end_at',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'start_at',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'interval_count',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'frequency',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'currency',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'amount',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'type',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'name',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'budgetId',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'categoryId',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'userId',
{ transaction }
);
await queryInterface.removeColumn(
'recurring_transaction_rules',
'merchant_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'fee_amount',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'tax_amount',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'source',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'flagged',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'description',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'reference_code',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'counterparty_name',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'transaction_at',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'currency',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'amount',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'status',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'type',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'categoryId',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'budgetId',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'userId',
{ transaction }
);
await queryInterface.removeColumn(
'transactions',
'merchant_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'alert_on_exceed',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'alert_threshold_percent',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'alert_on_threshold',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'status',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'currency',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'amount_limit',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'end_at',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'start_at',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'period',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'description',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'name',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'merchant_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'budgets',
'userId',
{ transaction }
);
await queryInterface.removeColumn(
'categories',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'categories',
'is_system',
{ transaction }
);
await queryInterface.removeColumn(
'categories',
'is_active',
{ transaction }
);
await queryInterface.removeColumn(
'categories',
'icon_key',
{ transaction }
);
await queryInterface.removeColumn(
'categories',
'color_hex',
{ transaction }
);
await queryInterface.removeColumn(
'categories',
'parent_categoryId',
{ transaction }
);
await queryInterface.removeColumn(
'categories',
'kind',
{ transaction }
);
await queryInterface.removeColumn(
'categories',
'name',
{ transaction }
);
await queryInterface.removeColumn(
'categories',
'merchant_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'user_sessions',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'user_sessions',
'revoked',
{ transaction }
);
await queryInterface.removeColumn(
'user_sessions',
'expires_at',
{ transaction }
);
await queryInterface.removeColumn(
'user_sessions',
'last_seen_at',
{ transaction }
);
await queryInterface.removeColumn(
'user_sessions',
'refresh_token_hash',
{ transaction }
);
await queryInterface.removeColumn(
'user_sessions',
'user_agent',
{ transaction }
);
await queryInterface.removeColumn(
'user_sessions',
'ip_address',
{ transaction }
);
await queryInterface.removeColumn(
'user_sessions',
'device_platform',
{ transaction }
);
await queryInterface.removeColumn(
'user_sessions',
'device_name',
{ transaction }
);
await queryInterface.removeColumn(
'user_sessions',
'userId',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'organizationsId',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'default_currency',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'timezone',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'country',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'postal_code',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'state',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'city',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'address_line2',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'address_line1',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'tax_number',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'business_phone',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'business_email',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'legal_name',
{ transaction }
);
await queryInterface.removeColumn(
'merchant_profiles',
'display_name',
{ transaction }
);
await queryInterface.removeColumn(
'organizations',
'name',
{ transaction }
);
await queryInterface.removeColumn(
'permissions',
'name',
{ transaction }
);
await queryInterface.removeColumn(
'roles',
'globalAccess',
{ transaction }
);
await queryInterface.removeColumn(
'roles',
'role_customization',
{ transaction }
);
await queryInterface.removeColumn(
'roles',
'name',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'organizationsId',
{ 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('support_messages', { transaction });
await queryInterface.dropTable('support_conversations', { transaction });
await queryInterface.dropTable('ai_insights', { transaction });
await queryInterface.dropTable('exchange_rates', { transaction });
await queryInterface.dropTable('user_preferences', { transaction });
await queryInterface.dropTable('activity_logs', { transaction });
await queryInterface.dropTable('notifications', { transaction });
await queryInterface.dropTable('scheduled_reports', { transaction });
await queryInterface.dropTable('reports', { transaction });
await queryInterface.dropTable('tasks', { transaction });
await queryInterface.dropTable('recurring_transaction_rules', { transaction });
await queryInterface.dropTable('transactions', { transaction });
await queryInterface.dropTable('budgets', { transaction });
await queryInterface.dropTable('categories', { transaction });
await queryInterface.dropTable('user_sessions', { transaction });
await queryInterface.dropTable('merchant_profiles', { transaction });
await queryInterface.dropTable('organizations', { 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;
}
}
};