metis-desk/modules/assets/src/api/domain/asset-catalog-seed.ts

146 lines
5.6 KiB
TypeScript
Raw Normal View History

import { UniqueID } from "@repo/rdx-ddd";
import type { AssetCatalog } from "./asset-catalog.aggregate";
import type { AssetDefinitionSpec, AssetFieldType } from "./asset-definition";
2026-10-09 08:38:19 +00:00
import { AssetDefinitionValues } from "./value-objects/asset-definition-values.vo";
const FIELDS: readonly [string, string, AssetFieldType, string][] = [
["brand", "Marca", "text", ""],
["model", "Modelo", "text", ""],
["serial", "Número de serie", "text", ""],
["processor", "Procesador", "text", ""],
["memory", "Memoria RAM", "number", "GB"],
["storage", "Almacenamiento", "text", ""],
["os", "Sistema operativo", "text", ""],
["hostname", "Nombre de equipo", "text", ""],
["screen_size", "Pulgadas", "number", "pulgadas"],
["resolution", "Resolución", "text", ""],
["connections", "Conexiones", "text", ""],
["ip", "Dirección IP", "text", ""],
["mac", "Dirección MAC", "text", ""],
["ports", "Número de puertos", "number", ""],
["speed", "Velocidad de red", "text", ""],
["poe", "PoE", "boolean", ""],
["wifi", "Estándar Wi-Fi", "text", ""],
["capacity", "Capacidad útil", "text", ""],
["disks", "Discos", "text", ""],
["raid", "RAID", "text", ""],
["printing", "Tecnología de impresión", "text", ""],
["color", "Impresión en color", "boolean", ""],
["duplex", "Doble cara", "boolean", ""],
["imei", "IMEI", "text", ""],
["phone", "Número de teléfono", "text", ""],
["carrier", "Operador móvil", "text", ""],
["power", "Potencia", "number", "VA"],
["battery", "Autonomía", "number", "minutos"],
["purchased_on", "Fecha de compra", "date", ""],
["warranty_until", "Fin de garantía", "date", ""],
];
const COMMON = ["brand", "model", "serial", "purchased_on", "warranty_until"];
const TEMPLATES: readonly [string, string, readonly string[]][] = [
[
"laptop",
"Portátil",
[
"processor",
"memory",
"storage",
"os",
"hostname",
"screen_size",
"resolution",
"connections",
"ip",
"mac",
],
],
[
"desktop",
"PC de sobremesa",
["processor", "memory", "storage", "os", "hostname", "connections", "ip", "mac"],
],
["monitor", "Monitor", ["screen_size", "resolution", "connections"]],
["printer", "Impresora", ["printing", "color", "duplex", "connections", "ip", "mac"]],
["router", "Router", ["ports", "speed", "wifi", "ip", "mac"]],
["firewall", "Firewall", ["ports", "speed", "ip", "mac"]],
["switch", "Switch", ["ports", "speed", "poe", "ip", "mac"]],
["access_point", "Punto de acceso Wi-Fi", ["wifi", "poe", "ip", "mac"]],
["nas", "NAS", ["processor", "memory", "disks", "capacity", "raid", "os", "ip", "mac"]],
[
"server",
"Servidor",
["processor", "memory", "storage", "disks", "raid", "os", "hostname", "ip", "mac"],
],
["smartphone", "Smartphone", ["os", "storage", "screen_size", "imei", "phone", "carrier"]],
["ups", "SAI", ["power", "battery", "connections"]],
];
const SECTION_FIELDS: readonly [string, readonly string[]][] = [
["Identificación", ["brand", "model", "serial"]],
["Hardware", ["processor", "memory", "storage", "capacity", "disks", "raid"]],
["Sistema", ["os", "hostname"]],
["Pantalla y conexiones", ["screen_size", "resolution", "connections"]],
["Red", ["ip", "mac", "ports", "speed", "poe", "wifi"]],
["Impresión", ["printing", "color", "duplex"]],
["Telefonía", ["imei", "phone", "carrier"]],
["Alimentación", ["power", "battery"]],
["Compra y garantía", ["purchased_on", "warranty_until"]],
];
export function seedAssetCatalog(catalog: AssetCatalog) {
let current = catalog;
const add = (key: string, input: AssetDefinitionSpec) => {
const values = AssetDefinitionValues.create(input);
if (!values.isSuccess) {
throw new Error("Definición inicial de activos inválida.");
}
const result = current.seed(key, values.data);
if (!result.isSuccess) {
throw new Error("Catálogo inicial de activos inconsistente.");
}
current = result.data;
};
for (const [key, name, type, unit] of FIELDS) {
add(`field:${key}`, { kind: "field", name, description: "", type, unit, choices: [] });
}
for (const [key, name, fields] of TEMPLATES) {
const sectionFields = [...COMMON, ...fields];
const sections = SECTION_FIELDS.filter(([, keys]) =>
keys.some((field) => sectionFields.includes(field))
).map(([name, keys]) => ({
id: UniqueID.generateNewID().toPrimitive(),
name,
description: "",
keys,
}));
const references = [...COMMON, ...fields].map((field) => {
const id = current.definitions
.find((item) => item.stockKey.getOrUndefined() === `field:${field}`)
?.id.toPrimitive();
if (!id) {
throw new Error("Campo inicial de activos ausente.");
}
const sectionId = sections.find((section) => section.keys.includes(field))?.id;
return { fieldId: id, required: false, ...(sectionId ? { sectionId } : {}) };
});
add(`template:${key}`, {
kind: "template",
name,
description: "",
fields: references,
...(sections.length
? { sections: sections.map(({ id, name, description }) => ({ id, name, description })) }
: {}),
});
}
2026-10-04 19:04:14 +00:00
for (const [key, name, inverseName, symmetric] of [
["connected", "Conectado a", "Conectado a", true],
["hosted", "Alojado en", "Aloja", false],
["depends", "Depende de", "Es necesario para", false],
["powered", "Alimentado por", "Alimenta", false],
["installed", "Instalado en", "Tiene instalado", false],
] as const) {
add(`relation:${key}`, { kind: "relation", name, inverseName, symmetric, description: "" });
}
return current;
}