90 lines
3.2 KiB
TypeScript
90 lines
3.2 KiB
TypeScript
|
|
import type { InferAttributes, InferCreationAttributes, Sequelize } from "sequelize";
|
||
|
|
import { DataTypes, Model, QueryTypes } from "sequelize";
|
||
|
|
export class AssetModel extends Model<
|
||
|
|
InferAttributes<AssetModel>,
|
||
|
|
InferCreationAttributes<AssetModel>
|
||
|
|
> {
|
||
|
|
declare id: string;
|
||
|
|
declare companyId: string;
|
||
|
|
declare templateId: string;
|
||
|
|
declare siteId: string | null;
|
||
|
|
declare personId: string | null;
|
||
|
|
declare specification: unknown;
|
||
|
|
declare values: unknown;
|
||
|
|
}
|
||
|
|
export class AssetRevisionModel extends Model<
|
||
|
|
InferAttributes<AssetRevisionModel>,
|
||
|
|
InferCreationAttributes<AssetRevisionModel>
|
||
|
|
> {
|
||
|
|
declare id: string;
|
||
|
|
declare assetId: string;
|
||
|
|
declare actorId: string;
|
||
|
|
declare recordedAt: string;
|
||
|
|
declare values: unknown;
|
||
|
|
declare position: number;
|
||
|
|
declare siteId: string | null;
|
||
|
|
declare personId: string | null;
|
||
|
|
}
|
||
|
|
const id = { type: DataTypes.UUID, primaryKey: true };
|
||
|
|
const fk = (model: string, nullable = false) => ({
|
||
|
|
type: DataTypes.UUID,
|
||
|
|
allowNull: nullable,
|
||
|
|
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 asset = {
|
||
|
|
id,
|
||
|
|
companyId: fk("companies"),
|
||
|
|
templateId: fk("asset_definitions"),
|
||
|
|
siteId: fk("company_sites", true),
|
||
|
|
personId: fk("company_contacts", true),
|
||
|
|
specification: { type: DataTypes.JSON, allowNull: false },
|
||
|
|
values: { type: DataTypes.JSON, allowNull: false },
|
||
|
|
};
|
||
|
|
const revision = {
|
||
|
|
id,
|
||
|
|
assetId: fk("assets"),
|
||
|
|
actorId: fk("users"),
|
||
|
|
siteId: fk("company_sites", true),
|
||
|
|
personId: fk("company_contacts", true),
|
||
|
|
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 === "assets")) {
|
||
|
|
await query.createTable("assets", asset);
|
||
|
|
}
|
||
|
|
if (!tables.some((table) => table.name === "asset_revisions")) {
|
||
|
|
await query.createTable("asset_revisions", revision);
|
||
|
|
}
|
||
|
|
const revisionColumns = await query.describeTable("asset_revisions");
|
||
|
|
for (const [column, reference] of [
|
||
|
|
["siteId", "company_sites"],
|
||
|
|
["personId", "company_contacts"],
|
||
|
|
] as const) {
|
||
|
|
if (!(column in revisionColumns)) {
|
||
|
|
await query.addColumn("asset_revisions", column, fk(reference, true));
|
||
|
|
}
|
||
|
|
// Reconstruye las referencias de instalaciones que ya hubieran registrado revisiones.
|
||
|
|
const source =
|
||
|
|
column === "siteId"
|
||
|
|
? "UPDATE asset_revisions SET siteId = NULLIF(JSON_UNQUOTE(JSON_EXTRACT(`values`, '$.siteId')), 'null')"
|
||
|
|
: "UPDATE asset_revisions SET personId = NULLIF(JSON_UNQUOTE(JSON_EXTRACT(`values`, '$.personId')), 'null')";
|
||
|
|
await database.query(
|
||
|
|
source + (column === "siteId" ? " WHERE siteId IS NULL" : " WHERE personId IS NULL")
|
||
|
|
);
|
||
|
|
}
|
||
|
|
AssetModel.init(asset, { sequelize: database, tableName: "assets", timestamps: false });
|
||
|
|
AssetRevisionModel.init(revision, {
|
||
|
|
sequelize: database,
|
||
|
|
tableName: "asset_revisions",
|
||
|
|
timestamps: false,
|
||
|
|
});
|
||
|
|
}
|