import type { InferAttributes, InferCreationAttributes, Sequelize } from "sequelize"; import { DataTypes, Model, QueryTypes } from "sequelize"; export class ResourceModel extends Model< InferAttributes, InferCreationAttributes > { declare id: string; declare companyId: string; declare templateId: string; declare specification: unknown; declare values: unknown; } export class ResourceRevisionModel extends Model< InferAttributes, InferCreationAttributes > { declare id: string; declare resourceId: string; declare actorId: string; declare recordedAt: string; declare values: unknown; declare position: number; } const id = { type: DataTypes.UUID, primaryKey: true }; const fk = (model: string) => ({ type: DataTypes.UUID, allowNull: false, references: { model, key: "id" }, onDelete: "RESTRICT", }); export async function migrateInventory(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 } ); const resource = { id, companyId: fk("companies"), templateId: fk("resource_definitions"), specification: { type: DataTypes.JSON, allowNull: false }, values: { type: DataTypes.JSON, allowNull: false }, }; const revision = { id, resourceId: fk("resources"), actorId: fk("users"), recordedAt: { type: DataTypes.STRING(30), allowNull: false }, values: { type: DataTypes.JSON, allowNull: false }, position: { type: DataTypes.INTEGER, allowNull: false }, }; if (!tables.some((table) => table.name === "resources")) { await query.createTable("resources", resource); } if (!tables.some((table) => table.name === "resource_revisions")) { await query.createTable("resource_revisions", revision); } const indexes = await database.query<{ name: string }>( "SELECT DISTINCT INDEX_NAME AS name FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='resource_revisions'", { type: QueryTypes.SELECT } ); if (!indexes.some((index) => index.name === "resource_revision_position_unique")) { await query.addIndex("resource_revisions", ["resourceId", "position"], { unique: true, name: "resource_revision_position_unique", }); } ResourceModel.init(resource, { sequelize: database, tableName: "resources", timestamps: false }); ResourceRevisionModel.init(revision, { sequelize: database, tableName: "resource_revisions", timestamps: false, }); }