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 15:57:05 +00:00
|
|
|
import { supportColumns } from "./asset-support-schema";
|
2026-10-10 11:32:40 +00:00
|
|
|
|
2026-10-07 08:16:39 +00:00
|
|
|
export async function migrateSupport(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
|
|
|
|
2026-10-07 08:16:39 +00:00
|
|
|
const fk = (model: string) => ({
|
|
|
|
|
type: DataTypes.UUID,
|
|
|
|
|
allowNull: false,
|
|
|
|
|
references: { model, key: "id" },
|
|
|
|
|
onDelete: "RESTRICT",
|
|
|
|
|
});
|
2026-10-10 10:01:58 +00:00
|
|
|
|
2026-10-07 08:16:39 +00:00
|
|
|
const definitions = [
|
|
|
|
|
[
|
|
|
|
|
"asset_support",
|
|
|
|
|
{
|
|
|
|
|
id: { type: DataTypes.UUID, primaryKey: true },
|
|
|
|
|
companyId: fk("companies"),
|
|
|
|
|
assetId: fk("assets"),
|
2026-10-10 16:21:06 +00:00
|
|
|
resourceId: { type: DataTypes.UUID, allowNull: false },
|
2026-10-10 11:32:40 +00:00
|
|
|
...supportColumns,
|
2026-10-07 08:16:39 +00:00
|
|
|
preferredKey: { type: DataTypes.UUID, allowNull: true, unique: true },
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
"asset_support_revisions",
|
|
|
|
|
{
|
|
|
|
|
id: { type: DataTypes.UUID, primaryKey: true },
|
|
|
|
|
connectionId: fk("asset_support"),
|
|
|
|
|
actorId: fk("users"),
|
2026-10-10 16:21:06 +00:00
|
|
|
resourceId: { type: DataTypes.UUID, allowNull: false },
|
2026-10-10 11:32:40 +00:00
|
|
|
...supportColumns,
|
2026-10-07 08:16:39 +00:00
|
|
|
recordedAt: { type: DataTypes.STRING(30), allowNull: false },
|
|
|
|
|
position: { type: DataTypes.INTEGER, allowNull: false },
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
] as const;
|
2026-10-10 10:01:58 +00:00
|
|
|
|
2026-10-07 08:16:39 +00:00
|
|
|
for (const [table, columns] of definitions) {
|
|
|
|
|
if (!tables.some((item) => item.name === table)) {
|
|
|
|
|
await query.createTable(table, columns);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const constraints = await database.query<{ name: string }>(
|
|
|
|
|
"SELECT CONSTRAINT_NAME AS name FROM information_schema.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='asset_support'",
|
|
|
|
|
{ type: QueryTypes.SELECT }
|
|
|
|
|
);
|
2026-10-10 10:01:58 +00:00
|
|
|
|
2026-10-07 08:16:39 +00:00
|
|
|
if (!constraints.some((item) => item.name === "support_asset_company")) {
|
|
|
|
|
await database.query(
|
|
|
|
|
"ALTER TABLE asset_support ADD CONSTRAINT support_asset_company FOREIGN KEY (companyId,assetId) REFERENCES assets(companyId,id)"
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-10-10 16:21:06 +00:00
|
|
|
const resourceIndexes = await database.query<{ name: string }>(
|
|
|
|
|
"SELECT DISTINCT INDEX_NAME AS name FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='resources'",
|
|
|
|
|
{ type: QueryTypes.SELECT }
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!resourceIndexes.some((index) => index.name === "resource_company_identity")) {
|
|
|
|
|
await query.addIndex("resources", ["companyId", "id"], {
|
|
|
|
|
unique: true,
|
|
|
|
|
name: "resource_company_identity",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
for (const table of ["asset_support", "asset_support_revisions"]) {
|
|
|
|
|
const existing = await database.query<{ name: string }>(
|
|
|
|
|
"SELECT CONSTRAINT_NAME AS name FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA=DATABASE() AND TABLE_NAME=:table",
|
|
|
|
|
{ replacements: { table }, type: QueryTypes.SELECT }
|
2026-10-07 08:16:39 +00:00
|
|
|
);
|
2026-10-10 16:21:06 +00:00
|
|
|
const name = `${table}_resource_reference`;
|
|
|
|
|
|
|
|
|
|
if (!existing.some((item) => item.name === name)) {
|
|
|
|
|
await database.query(
|
|
|
|
|
`ALTER TABLE ${table} ADD CONSTRAINT ${name} FOREIGN KEY (resourceId) REFERENCES resources(id) ON DELETE RESTRICT`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (
|
|
|
|
|
table === "asset_support" &&
|
|
|
|
|
!existing.some((item) => item.name === "support_resource_company")
|
|
|
|
|
) {
|
|
|
|
|
await database.query(
|
|
|
|
|
"ALTER TABLE asset_support ADD CONSTRAINT support_resource_company FOREIGN KEY (companyId,resourceId) REFERENCES resources(companyId,id) ON DELETE RESTRICT"
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-10-07 08:16:39 +00:00
|
|
|
}
|
|
|
|
|
}
|