import { DataTypes, QueryTypes, type Sequelize } from "sequelize"; export async function migrateMailConfigurations(database: Sequelize) { const query = database.getQueryInterface(); const rows = await database.query<{ name: string }>( "SELECT TABLE_NAME AS name FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE()", { type: QueryTypes.SELECT } ); const reference = (table: string) => ({ type: DataTypes.UUID, allowNull: false, references: { model: table, key: "id" }, onDelete: "RESTRICT", }); if (!rows.some((row) => row.name === "mail_configurations")) { await query.createTable("mail_configurations", { id: { type: DataTypes.UUID, primaryKey: true }, companyId: reference("companies"), personId: { ...reference("company_contacts"), allowNull: true }, accountId: { ...reference("access_items"), allowNull: true }, assetId: { ...reference("assets"), allowNull: true }, profileId: { ...reference("work_profiles"), allowNull: true }, mailboxId: { ...reference("mailboxes"), allowNull: true }, values: { type: DataTypes.JSON, allowNull: false }, currentKey: { type: DataTypes.STRING(110), allowNull: true, unique: true }, }); } if (!rows.some((row) => row.name === "mail_configuration_revisions")) { await query.createTable("mail_configuration_revisions", { id: { type: DataTypes.UUID, primaryKey: true }, configurationId: reference("mail_configurations"), position: { type: DataTypes.INTEGER, allowNull: false }, actorId: reference("users"), recordedAt: { type: DataTypes.STRING(24), allowNull: false }, values: { type: DataTypes.JSON, allowNull: false }, }); } const columns = await query.describeTable("mail_configurations"); for (const [column, table] of [ ["personId", "company_contacts"], ["accountId", "access_items"], ["assetId", "assets"], ["profileId", "work_profiles"], ["mailboxId", "mailboxes"], ] as const) { if (!columns[column]) { await query.addColumn("mail_configurations", column, { ...reference(table), allowNull: true, }); } else if (!columns[column].allowNull) { await query.changeColumn("mail_configurations", column, { type: DataTypes.UUID, allowNull: true, }); } } const indexes = await database.query<{ name: string }>( "SELECT DISTINCT INDEX_NAME AS name FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='mail_configuration_revisions'", { type: QueryTypes.SELECT } ); if (!indexes.some((index) => index.name === "mail_revision_position")) { await query.addIndex("mail_configuration_revisions", ["configurationId", "position"], { unique: true, name: "mail_revision_position", }); } }