133 lines
5.2 KiB
TypeScript
133 lines
5.2 KiB
TypeScript
|
|
import type { Sequelize } from "sequelize";
|
||
|
|
import { DataTypes, QueryTypes } from "sequelize";
|
||
|
|
|
||
|
|
const fk = (model: string, nullable = false) => ({
|
||
|
|
type: DataTypes.UUID,
|
||
|
|
allowNull: nullable,
|
||
|
|
references: { model, key: "id" },
|
||
|
|
onDelete: ["resource_definitions", "access_items"].includes(model) ? "RESTRICT" : "CASCADE",
|
||
|
|
});
|
||
|
|
|
||
|
|
const title = { type: DataTypes.STRING(100), allowNull: false };
|
||
|
|
const position = { type: DataTypes.INTEGER, allowNull: false };
|
||
|
|
|
||
|
|
export const definitionColumns = {
|
||
|
|
kind: { type: DataTypes.STRING(12), allowNull: false },
|
||
|
|
name: title,
|
||
|
|
description: { type: DataTypes.TEXT, allowNull: false },
|
||
|
|
fieldType: { type: DataTypes.STRING(12), allowNull: true },
|
||
|
|
unit: { type: DataTypes.STRING(30), allowNull: true },
|
||
|
|
usage: { type: DataTypes.STRING(15), allowNull: true },
|
||
|
|
sectionsDefined: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false },
|
||
|
|
};
|
||
|
|
|
||
|
|
export const inventoryColumns = {
|
||
|
|
name: title,
|
||
|
|
active: { type: DataTypes.BOOLEAN, allowNull: false },
|
||
|
|
notes: { type: DataTypes.TEXT, allowNull: false },
|
||
|
|
integrationKind: { type: DataTypes.STRING(10), allowNull: true },
|
||
|
|
addressFieldId: fk("resource_definitions", true),
|
||
|
|
contextFieldId: fk("resource_definitions", true),
|
||
|
|
mailboxKind: { type: DataTypes.STRING(10), allowNull: true },
|
||
|
|
accountId: fk("access_items", true),
|
||
|
|
referenceFieldId: fk("resource_definitions", true),
|
||
|
|
resourceTypeId: fk("access_items", true),
|
||
|
|
systemId: fk("access_items", true),
|
||
|
|
environmentId: fk("access_items", true),
|
||
|
|
};
|
||
|
|
|
||
|
|
export const specificationColumns = {
|
||
|
|
templateName: title,
|
||
|
|
sectionsDefined: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false },
|
||
|
|
};
|
||
|
|
|
||
|
|
type Columns = Parameters<ReturnType<Sequelize["getQueryInterface"]>["createTable"]>[1];
|
||
|
|
|
||
|
|
async function create(database: Sequelize, name: string, columns: Columns) {
|
||
|
|
const tables = await database.query<{ name: string }>(
|
||
|
|
"SELECT TABLE_NAME AS name FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=:name",
|
||
|
|
{ replacements: { name }, type: QueryTypes.SELECT }
|
||
|
|
);
|
||
|
|
|
||
|
|
if (!tables.length) {
|
||
|
|
await database.getQueryInterface().createTable(name, columns);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function initializeResourceCatalogSchema(database: Sequelize) {
|
||
|
|
await create(database, "resource_field_choices", {
|
||
|
|
fieldId: { ...fk("resource_definitions"), primaryKey: true },
|
||
|
|
position: { ...position, primaryKey: true },
|
||
|
|
value: title,
|
||
|
|
});
|
||
|
|
await create(database, "resource_template_sections", {
|
||
|
|
id: { type: DataTypes.UUID, primaryKey: true },
|
||
|
|
templateId: { ...fk("resource_definitions"), primaryKey: true },
|
||
|
|
name: title,
|
||
|
|
description: { type: DataTypes.TEXT, allowNull: false },
|
||
|
|
position,
|
||
|
|
});
|
||
|
|
await constrainSections(database);
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function initializeResourceInventorySchema(database: Sequelize) {
|
||
|
|
await create(database, "resource_specification_sections", {
|
||
|
|
resourceId: { ...fk("resources"), primaryKey: true },
|
||
|
|
id: { type: DataTypes.UUID, primaryKey: true },
|
||
|
|
name: title,
|
||
|
|
description: { type: DataTypes.TEXT, allowNull: false },
|
||
|
|
position,
|
||
|
|
});
|
||
|
|
await create(database, "resource_specification_fields", {
|
||
|
|
resourceId: { ...fk("resources"), primaryKey: true },
|
||
|
|
fieldId: { ...fk("resource_definitions"), primaryKey: true },
|
||
|
|
name: title,
|
||
|
|
fieldType: { type: DataTypes.STRING(12), allowNull: false },
|
||
|
|
unit: { type: DataTypes.STRING(30), allowNull: false },
|
||
|
|
required: { type: DataTypes.BOOLEAN, allowNull: false },
|
||
|
|
sectionId: { type: DataTypes.UUID, allowNull: true },
|
||
|
|
position,
|
||
|
|
});
|
||
|
|
await create(database, "resource_specification_field_choices", {
|
||
|
|
resourceId: { ...fk("resources"), primaryKey: true },
|
||
|
|
fieldId: { ...fk("resource_definitions"), primaryKey: true },
|
||
|
|
position: { ...position, primaryKey: true },
|
||
|
|
value: title,
|
||
|
|
});
|
||
|
|
const typedValues = {
|
||
|
|
fieldId: { ...fk("resource_definitions"), primaryKey: true },
|
||
|
|
valueType: { type: DataTypes.STRING(12), allowNull: false },
|
||
|
|
textValue: { type: DataTypes.TEXT, allowNull: true },
|
||
|
|
numberValue: { type: DataTypes.DOUBLE, allowNull: true },
|
||
|
|
booleanValue: { type: DataTypes.BOOLEAN, allowNull: true },
|
||
|
|
dateValue: { type: DataTypes.DATEONLY, allowNull: true },
|
||
|
|
};
|
||
|
|
|
||
|
|
await create(database, "resource_characteristics", {
|
||
|
|
resourceId: { ...fk("resources"), primaryKey: true },
|
||
|
|
...typedValues,
|
||
|
|
});
|
||
|
|
await create(database, "resource_revision_characteristics", {
|
||
|
|
revisionId: { ...fk("resource_revisions"), primaryKey: true },
|
||
|
|
resourceId: fk("resources"),
|
||
|
|
...typedValues,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
async function constrainSections(database: Sequelize) {
|
||
|
|
const constraints = await database.query<{ name: string }>(
|
||
|
|
"SELECT CONSTRAINT_NAME AS name FROM information_schema.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='resource_template_fields' AND CONSTRAINT_NAME='resource_template_field_section'",
|
||
|
|
{ type: QueryTypes.SELECT }
|
||
|
|
);
|
||
|
|
|
||
|
|
if (!constraints.length) {
|
||
|
|
await database.query(
|
||
|
|
"ALTER TABLE resource_template_fields ADD CONSTRAINT resource_template_field_section FOREIGN KEY (templateId,sectionId) REFERENCES resource_template_sections(templateId,id)"
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function enforceResourceConstraints(database: Sequelize) {
|
||
|
|
await constrainSections(database);
|
||
|
|
}
|