metis-desk/modules/companies/src/api/infrastructure/persistence/mailbox-migration.ts

85 lines
2.5 KiB
TypeScript
Raw Normal View History

2026-10-08 14:43:34 +00:00
import type { Sequelize } from "sequelize";
import { DataTypes, QueryTypes } from "sequelize";
2026-10-10 10:01:58 +00:00
2026-10-10 14:40:51 +00:00
import { mailboxSnapshot, mailboxUseSnapshot } from "./mail-remote-snapshots";
export async function migrateMailboxes(database: Sequelize) {
const query = database.getQueryInterface();
const tables = await database.query<{ name: string }>(
"SELECT TABLE_NAME AS name FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE()",
{ type: QueryTypes.SELECT }
);
2026-10-10 10:01:58 +00:00
const fk = (table: string, nullable = false) => ({
type: DataTypes.UUID,
allowNull: nullable,
references: { model: table, key: "id" },
onDelete: "RESTRICT",
});
2026-10-10 10:01:58 +00:00
const root = {
id: { type: DataTypes.UUID, primaryKey: true },
companyId: fk("companies"),
};
2026-10-10 10:01:58 +00:00
for (const [table, columns] of [
[
"mailboxes",
{
...root,
2026-10-10 14:40:51 +00:00
...mailboxSnapshot.columns,
accountId: fk("access_items", true),
addressKey: { type: DataTypes.STRING(300), allowNull: false, unique: true },
},
],
2026-10-10 14:40:51 +00:00
[
"mailbox_uses",
{
...root,
...mailboxUseSnapshot.columns,
mailboxId: fk("mailboxes"),
personId: fk("company_contacts"),
},
],
[
"mailbox_revisions",
{
id: root.id,
itemId: fk("mailboxes"),
position: { type: DataTypes.INTEGER, allowNull: false },
2026-10-10 14:40:51 +00:00
...mailboxSnapshot.columns,
actorId: fk("users"),
recordedAt: { type: DataTypes.STRING(24), allowNull: false },
},
],
[
"mailbox_use_revisions",
{
id: root.id,
itemId: fk("mailbox_uses"),
position: { type: DataTypes.INTEGER, allowNull: false },
2026-10-10 14:40:51 +00:00
...mailboxUseSnapshot.columns,
actorId: fk("users"),
recordedAt: { type: DataTypes.STRING(24), allowNull: false },
},
],
] as const) {
if (!tables.some((row) => row.name === table)) {
await query.createTable(table, columns);
}
}
for (const table of ["mailbox_revisions", "mailbox_use_revisions"]) {
const indexes = await database.query<{ name: string }>(
"SELECT DISTINCT INDEX_NAME AS name FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=:table",
{ replacements: { table }, type: QueryTypes.SELECT }
);
2026-10-10 10:01:58 +00:00
if (!indexes.some((item) => item.name === `${table}_position`)) {
await query.addIndex(table, ["itemId", "position"], {
unique: true,
name: `${table}_position`,
});
}
}
}