metis-desk/modules/assets/src/api/infrastructure/persistence/asset-relational-schema.ts

109 lines
4.0 KiB
TypeScript
Raw Normal View History

2026-10-10 15:57:05 +00:00
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: model === "asset_definitions" ? "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 },
icon: { type: DataTypes.STRING(30), allowNull: true },
2026-10-10 15:57:05 +00:00
fieldType: { type: DataTypes.STRING(12), allowNull: true },
unit: { type: DataTypes.STRING(30), allowNull: true },
inverseName: { ...title, allowNull: true },
symmetric: { type: DataTypes.BOOLEAN, allowNull: true },
sectionsDefined: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false },
};
export const inventoryColumns = {
name: title,
status: { type: DataTypes.STRING(15), allowNull: false },
notes: { type: DataTypes.TEXT, allowNull: false },
brandDefined: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false },
};
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 initializeAssetCatalogSchema(database: Sequelize) {
await create(database, "asset_field_choices", {
fieldId: { ...fk("asset_definitions"), primaryKey: true },
position: { ...position, primaryKey: true },
value: title,
});
await create(database, "asset_template_sections", {
id: { type: DataTypes.UUID, primaryKey: true },
templateId: fk("asset_definitions"),
name: title,
description: { type: DataTypes.TEXT, allowNull: false },
position,
});
}
export async function initializeAssetInventorySchema(database: Sequelize) {
await create(database, "asset_specification_sections", {
assetId: { ...fk("assets"), primaryKey: true },
id: { type: DataTypes.UUID, primaryKey: true },
name: title,
description: { type: DataTypes.TEXT, allowNull: false },
position,
});
await create(database, "asset_specification_fields", {
assetId: { ...fk("assets"), primaryKey: true },
fieldId: { ...fk("asset_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, "asset_specification_field_choices", {
assetId: { ...fk("assets"), primaryKey: true },
fieldId: { ...fk("asset_definitions"), primaryKey: true },
position: { ...position, primaryKey: true },
value: title,
});
const typedValues = {
fieldId: { ...fk("asset_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, "asset_characteristics", {
assetId: { ...fk("assets"), primaryKey: true },
...typedValues,
});
await create(database, "asset_revision_characteristics", {
revisionId: { ...fk("asset_revisions"), primaryKey: true },
assetId: fk("assets"),
...typedValues,
});
}