9.4 KiB
02 — Plantillas y Aplicación
Dos ámbitos distintos
CONFIRMADO: ResourceCatalog es un agregado global (catalogKey='global'), con ResourceDefinition de tipo field o template; cada definición tiene companyId: Maybe<UniqueID>. NULL en resource_definitions.companyId ya significa definición global. ResourceCatalog.visible(company) combina globales y locales de esa compañía. resource_availability ajusta disponibilidad de definiciones globales por compañía. Esto no convierte en global a un Resource registrado con ellas. catalog: resource-catalog.aggregate.ts:14 catalogSQL: resource-catalog.model.ts:48 visible: resource-catalog.aggregate.ts:41.
| Elemento | Persistencia | Ámbito/propiedad | Reglas |
|---|---|---|---|
| ResourceCatalog | resource_catalogs | Raíz global única por catalogKey | Composición explícita |
| ResourceDefinition | resource_definitions | Global o compañía | UUID propio; stockKey nullable y unique; active |
| Campo | definición kind=field + resource_field_choices | Global/local | text, number, date, boolean, choice; tipo fijo; no retirar opciones existentes |
| Plantilla | definición kind=template | Global/local | 1..100 bindings, 0..30 secciones opcionales; usage opcional |
| TemplateField | resource_template_fields | Propiedad de plantilla | ID propio, fieldId, required, position, sectionId |
| TemplateSection | resource_template_sections | Propiedad de plantilla | ID, nombre, descripción, orden |
| CatalogAvailability | resource_availability | Compañía + definición | active nullable: heredar, habilitar, deshabilitar; par unique |
Fuentes: definition: resource-definition.ts:23 definitionEntity: resource-definition.entity.ts:35 catalogSQL: resource-catalog.model.ts:48. Una plantilla global admite solo campos globales; una local admite globales y propios. Son configurables en ejecución mediante HTTP, no herencia de clases. Una copia es otra definición, no herencia viva. usage queda fijo al actualizar. No hay número de versión de plantilla; las especificaciones de recursos y sus revisiones proporcionan instantáneas. catalog: resource-catalog.aggregate.ts:14 propagation: prepare-resource-template-updates.ts:15.
Identificación real de Aplicación
CONFIRMADO: el seed busca stockKey='template:application'; el UUID se genera/preserva en la instalación. No debe fijarse un UUID universal ni filtrar por el texto «Aplicación». Transporte expone builtinKey y el indicador builtin. ResourceInventoryService.resourceUsage reconoce la clave de serie, y para plantillas propias usa definition.usage. El selector de perfiles aplica builtinKey === 'template:application' || usage === 'application'. seed: resource-catalog-seed.ts:140 usage: resource-inventory.service.ts:54 catalogDTO: index.ts:19 applicationOptions: application-configuration-form-values.ts:8.
La plantilla de serie Aplicación no necesita persistir usage='application' para ser reconocida: su stockKey lo determina. resourceTemplateCapability solo devuelve capacidades para dominio Windows y carpeta SMB; no existe una capability de aplicación en esa función. Clasificación operativa usage, stockKey, propiedad companyId y capability cumplen responsabilidades diferentes. capability: resource-capabilities.ts:2.
Campos del producto disponibles
CONFIRMADO: plantilla inicial Aplicación: provider, url, description, todos opcionales. Tipos text, sin unidad ni opciones. Nombre comercial es values.name, actividad values.active y observaciones values.notes, comunes a Resource. Seed actual declara 22 campos y 9 plantillas; la mención «20 campos y seis plantillas» de docs/recursos-campos-y-plantillas.md está desactualizada respecto al código y no se corrigió fuera del alcance. seedfields: resource-catalog-seed.ts:9 seed: resource-catalog-seed.ts:140.
| Candidato | Existe realmente | Semántica/validación | Decisión propuesta |
|---|---|---|---|
| Nombre comercial | values.name | Name, 1..100, UUID independiente | Reutilizar |
| Fabricante | field:provider → UUID dinámico | Texto libre, etiqueta Proveedor | Reutilizar; filtro textual sin entidad Manufacturer implícita |
| Descripción | field:description | Texto ≤10000 por valor | Reutilizar |
| Sitio oficial | field:url | Texto; no validador URL específico | Reutilizar, definir validación de URL si se necesita |
| Estado | values.active | Boolean | Reutilizar |
| Categoría | No en Aplicación de serie | Campo configurable posible | No prometer filtro hasta aprobar campo/semántica |
| Familia de producto | No en serie | No relación canónica | Posponer hasta necesidad real |
| Identificador externo | No tipado/único | field:reference existe en catálogo, no ligado aquí | No usar nombre como ID canónico; diseño externo pendiente |
| Plataforma/SO compatible | No en Aplicación de serie | No colección/relación tipada | Decidir cardinalidad antes de ampliar; no JSON por comodidad |
Campos de serie pueden haberse editado en una instalación: el seed no restablece de forma destructiva el catálogo. NO CONFIRMADO: contenido efectivo de plantillas en una BD no consultada. catalog: resource-catalog.aggregate.ts:14.
Versión instalada pertenece a SoftwareInstallation; versión y delivery por perfil a ApplicationConfiguration; licencia, cantidad, caducidad y renovación a Resource de uso license local; fechas de instalación y política corporativa no se presuponen implementadas. No trasladar estados de preparación/retirada ni credenciales al producto global. softwareInput: software-installation-values.ts:5 applicationInput: application-configuration-values.ts:5.
Propagación y disponibilidad
prepareResourceTemplateUpdates detecta plantillas/campos cambiados, enumera compañías con Resource de esas plantillas, bloquea compañías y reconstruye especificación. Conserva valores de campos retirados según sincronización; no inventa obligatorios nuevos. Cada recurso modificado incorpora revisión. El bucle presupone companyId: string: con NULL se debe añadir una rama global explícita, mantener lock order y evitar validar campos globales en un contexto local equivocado. propagation: prepare-resource-template-updates.ts:15.
Desactivar una definición impide altas según captureResourceSpecification, sin invalidar automáticamente recursos ya creados. No confundir esa disponibilidad de plantilla con Resource.values.active. Propuesta: bloqueo local de una plantilla puede impedir nuevas selecciones, pero nunca ocultar referencias históricas. Decidir esta política expresamente. capture: resource-input.mapper.ts:69.
Qué plantillas admitir
| Alternativa | Ventajas | Costes y riesgos | Compatibilidad |
|---|---|---|---|
| Solo Aplicación de serie | Alcance mínimo, clave estable, campos globales controlados | No engloba inmediatamente todas las plantillas propias | Recomendación de lanzamiento; permitir locales existentes en selectores |
| Scope genérico habilitable por plantilla | Extensible a otras definiciones reutilizables | Requiere contrato globalEligible, validación de campos/integ./consumidores y administración | Diseñar discriminación genérica, habilitar después de auditar cada uso |
PROPUESTO: representación de ámbito reutilizable en Resource, con allowlist inicial de template:application, sin integración mailbox/access ni proyecciones operativas. Una plantilla propia de compañía nunca puede producir un Resource global. Una plantilla global personalizada con uso application solo se habilitaría mediante decisión posterior explícita; usage por sí solo no acredita que sus datos sean públicos. Copias locales siguen produciendo recursos de compañía. No globalizar OS, support, certificate, license, SMB o dominios por ampliar el tipo. Véase 09.