import { UniqueID } from "@repo/rdx-ddd"; import type { ResourceCatalog } from "./resource-catalog.aggregate"; import type { ResourceDefinitionSpec, ResourceFieldType } from "./resource-definition"; import { ResourceDefinitionValues } from "./value-objects/resource-definition-values.vo"; const FIELDS: readonly [string, string, ResourceFieldType, string, (readonly string[])?][] = [ [ "email", "Dirección de correo", "text", "Indica la dirección completa del buzón. Ejemplo: soporte@empresa.es.", ], [ "provider", "Proveedor", "text", "Indica el proveedor o fabricante del servicio. Ejemplo: Microsoft 365.", ], [ "context", "Contexto", "text", "Aclara el uso, área o persona a la que está destinado. Ejemplo: facturación.", ], ["unc", "Ruta UNC", "text", "Usa la ruta de red completa. Ejemplo: \\servidor\\contabilidad."], [ "server", "Servidor (referencia documental)", "text", "Anota el servidor que publica el recurso, si se conoce. Ejemplo: FS-01.", ], [ "description", "Descripción", "text", "Añade los detalles necesarios para identificar o utilizar el recurso. Ejemplo: acceso solo para administración.", ], [ "url", "URL", "text", "Incluye la dirección web de acceso o de documentación. Ejemplo: https://portal.empresa.es.", ], [ "holder", "Titular", "text", "Indica la persona u organización titular del certificado. Ejemplo: Empresa S. L.", ], [ "issuer", "Emisor", "text", "Indica la entidad que emitió el certificado. Ejemplo: Let's Encrypt.", ], [ "expires", "Caducidad", "date", "Indica la fecha en la que deja de ser válido. Ejemplo: 2027-06-30.", ], [ "fingerprint", "Huella digital", "text", "Copia la huella o identificador único del certificado. Ejemplo: SHA-256 A1:B2:C3:…", ], [ "purpose", "Finalidad", "text", "Explica qué servicio, proceso o equipo utiliza este recurso. Ejemplo: firma de facturas.", ], [ "reference", "Referencia", "text", "Registra el identificador, número de contrato o referencia del proveedor. Ejemplo: contrato MS-2026-014.", ], [ "software_product", "Producto de software", "text", "Indica el nombre comercial del producto licenciado. Ejemplo: Microsoft 365 Business Premium.", ], [ "software_edition", "Edición o plan", "text", "Indica la edición, nivel o plan contratado. Ejemplo: Enterprise E3.", ], [ "license_model", "Modalidad de licencia", "choice", "Selecciona cómo se adquiere o mantiene la licencia. Ejemplo: Suscripción.", ["Suscripción", "Perpetua", "OEM", "Otra"], ], [ "license_metric", "Criterio de licenciamiento", "choice", "Selecciona la unidad con la que se calcula la cobertura contratada. Ejemplo: Por usuario.", ["Por usuario", "Por dispositivo", "Por servidor", "Concurrente", "Corporativa", "Otro"], ], [ "license_quantity", "Cantidad contratada", "number", "Indica el número de licencias o unidades cubiertas. Ejemplo: 25.", ], [ "renews", "Fecha de renovación", "date", "Indica la próxima fecha prevista de renovación. Ejemplo: 2027-01-01.", ], [ "auto_renew", "Renovación automática", "boolean", "Marca si la renovación se realiza automáticamente. Ejemplo: Sí si el proveedor carga el siguiente periodo.", ], ]; const TEMPLATES: readonly [string, string, readonly string[]][] = [ ["mailbox", "Buzón de correo", ["email", "provider", "context"]], ["access", "Recurso de acceso", ["reference"]], ["shared_folder", "Carpeta compartida", ["unc", "server", "description"]], ["support", "Herramienta de asistencia remota", ["provider", "url", "description"]], ["os", "Sistema operativo", ["provider", "software_edition", "description"]], ["application", "Aplicación", ["provider", "url", "description"]], ["certificate", "Certificado digital", ["holder", "issuer", "expires", "fingerprint", "purpose"]], [ "software_license", "Licencia de software", [ "software_product", "software_edition", "provider", "license_model", "license_metric", "license_quantity", "reference", "expires", "renews", "auto_renew", "description", ], ], ]; /** Solo alimenta definiciones; no crea recursos ni migra registros anteriores. */ const SECTION_FIELDS: readonly [string, readonly string[]][] = [ ["Identificación", ["holder", "issuer", "fingerprint"]], ["Producto", ["software_product", "software_edition", "provider"]], ["Contratación", ["license_model", "license_metric", "license_quantity", "reference"]], ["Vigencia y renovación", ["expires", "renews", "auto_renew"]], ["Uso y observaciones", ["purpose", "description"]], ]; export function seedResourceCatalog(catalog: ResourceCatalog) { let current = catalog; const add = (key: string, input: ResourceDefinitionSpec) => { const values = ResourceDefinitionValues.create(input); if (!values.isSuccess) { throw new Error("Definición inicial de recursos inválida."); } const result = current.seed(key, values.data); if (!result.isSuccess) { throw new Error("Catálogo inicial de recursos inconsistente."); } current = result.data; }; for (const [key, name, type, description, choices] of FIELDS) { add(`field:${key}`, { kind: "field", name, description, type, unit: "", choices: [...(choices ?? [])], }); } for (const [key, name, fields] of TEMPLATES) { const sectionFields = fields; const sections = (fields.length > 3 ? SECTION_FIELDS : []) .filter(([, keys]) => keys.some((field) => sectionFields.includes(field))) .map(([name, keys]) => ({ id: UniqueID.generateNewID().toPrimitive(), name, description: "", keys, })); const references = fields.map((field) => { const id = current.definitions .find((item) => item.stockKey.getOrUndefined() === `field:${field}`) ?.id.toPrimitive(); if (!id) { throw new Error("Campo inicial de recursos ausente."); } const sectionId = sections.find((section) => section.keys.includes(field))?.id; return { fieldId: id, required: false, ...(sectionId ? { sectionId } : {}) }; }); add(`template:${key}`, { kind: "template", ...(key === "support" || key === "os" ? { usage: key } : {}), name, description: "", fields: references, ...(sections.length ? { sections: sections.map(({ id, name, description }) => ({ id, name, description })) } : {}), }); } return current; }