9.4 KiB
09 — Alternativas arquitectónicas
Todas las alternativas son PROPUESTAS, no contratos aprobados. Base confirmada: Resource exige dueño; las definiciones admiten NULL global; instalaciones/configuraciones referencian resources.id con FK simple; ámbitos operativos SMB/directorio/asistencia tienen FKs compuestas. owner: resource.aggregate.ts:11 catalogSQL: resource-catalog.model.ts:48 softwareFK: software-installation-snapshot.ts:7 applicationFK: configuration-snapshots.ts:57 supportSQL: support-migration.ts:86.
Cuatro diseños
A — Resource con ámbito explícito. Una raíz y tabla Resource con scope global/company; companyId NULL para global, UUID para company. CHECK de coherencia y discriminación en dominio/DTO. Mantiene un producto global como Resource sin copia. Coste: redundancia controlada, migración y adaptación de contratos.
B — Resource con ámbito derivado. Misma tabla; ausencia de companyId representa global, sin scope persistido. Un scope de presentación podría derivarse. Precedente real en ResourceDefinition y AccessWorkspace; evita estados contradictorios. Coste: NULL adquiere significado de privilegio/visibilidad y todos los consumidores deben distinguirlo de ausencia/corrupción. Se puede representar con Maybe en dominio, como definiciones; no es inseguro por naturaleza si se valida igual que A.
C — ApplicationCatalog separado más Resource por compañía. Una nueva definición global ApplicationCatalog, enlazada desde copias Resource locales. Mantiene gran parte del contrato actual no nullable, pero hay dos identidades/estructuras del producto y sincronización. El caso solicitado exige que el producto compartido siga siendo Resource y que no se cree una copia por compañía: C no cumple ese objetivo tal como se plantea.
D — Resource canónico global más asociación de adopción por compañía. El producto sigue siendo Resource global y una entidad relacional CompanyResourceUsage/Adoption documenta disponibilidad/política local. Instalaciones/configuraciones apuntan al canónico, con asociación validada. No copia el producto; permite política corporativa y revocación local independientes de active global. Añade identidad, historial y administración que no tienen consumidor requerido todavía. Se apoya conceptualmente en separación definición/disponibilidad ya existente, pero no hay tal asociación de adopción de Resource implementada.
Comparación
| Criterio | A | B | C | D |
|---|---|---|---|---|
| Compatibilidad actual | Cambia raíz/DTO; FKs simples preservadas | Mismos cambios por NULL, menos columna | Preserva dueño local, introduce nuevo modelo | Cambia raíz como A/B y añade asociación |
| Complejidad de migración | Media/alta transversal | Media/alta, sin backfill scope | Alta: nueva entidad, mapeo y copias | Alta: ámbito + tabla + adopciones |
| Integridad | CHECK de par; policy intertablas | Sin combinación inválida; policy intertablas | Dos fuentes de producto y coherencia de copias | FK adopción útil, policy de tipo/ámbito sigue necesaria |
| Aislamiento | Explícito por intención/propósito; no basta scope | Igual garantía si policy correcta | Aislamiento legacy local fuerte; sincronización nueva | Aislamiento por pertenencia y adopción |
| Reutilización Resource | Completa, sin copias | Completa, sin copias | Producto global deja de ser Resource único | Completa, sin copias |
| Rendimiento | Mixto indexable; medir OR/UNION | Muy similar a A; medir NULL/index | Joins/sincronización de copias | Joins de asociación y resolución |
| Extensibilidad | Tipo cerrado y allowlist por plantilla | Deducir ámbito no restringe futura policy | Acopla catálogo a aplicaciones | Políticas locales futuras explícitas |
| Historial | Resource único + relaciones locales independientes | Igual | Divergencia canónico/copias; migración compleja | Añade historial de adopción, además de los anteriores |
| Control corporativo | No añade permiso de usar por compañía | Igual | Copia local podría tener política, duplicada | Sí, si existe requisito aprobado |
| Datos existentes | Todos se etiquetan company; IDs intactos | Permanecen con UUID | Requiere asociación al catálogo para adoptar | Requiere definir adopciones, nunca inventarlas |
La complejidad es cualitativa y relativa al código revisado, no estimación de jornadas ni métricas. A y B tienen costes de adaptación parecidos: eliminar la columna scope no elimina el problema de resolver globales ni el de autorizar escrituras.
Recomendación
PROPUESTO: A, ampliando Resource, con scope explícito y companyId nullable, CHECK de coherencia, propiedad inmutable y globales restringidos inicialmente a plantilla de serie Aplicación. La ventaja de A frente a B es declarar la intención en comandos, dominio, respuestas y revisión de seguridad; una misma ausencia companyId ya no basta como contrato de alta global. La redundancia solo se acepta si hay constraint, schemas discriminados y una fuente de validación común, sin scope inferido de parámetros opcionales dispersos.
B es una alternativa viable, más cercana a ResourceDefinition y con menor redundancia. Si se prioriza simetría de dominio y esquema, puede aprobarse B conservando idénticos controles de autorización, elegibilidad y resolución por finalidad. Esta auditoría no atribuye a scope una garantía que ya no pueda obtenerse con B. La elección A/B debe cerrarse antes de migrar.
Rechazar C para esta misión por duplicación y doble modelo. Posponer D hasta que exista requisito real de adopción/política específica: poder consultar la definición global no significa estar autorizado contractualmente a usar el software. No añadir una entidad de adopción como sustituto improvisado de licencias o permisos de acceso.
Invariantes finales propuestas
- Resource global es definición reutilizable; no es instalación, configuración, derecho de uso ni permiso.
- Scope/owner y templateId no cambian por update ordinario. No convertir local a global porque se hayan encontrado nombres iguales.
- Global requiere plantilla elegible de ámbito global y campos globales, sin integración Access/Mailbox ni proyecciones SMB/directorio.
- Primer lanzamiento: solo stockKey template:application. Recursos locales de uso application siguen válidos, incluidas plantillas propias. No globalizar todas las plantillas con usage application sin aprobación.
- El contexto C autoriza al operador; cada asociación acepta global elegible o local de C. Licencia, activo y perfil se validan localmente por separado.
- Referencia por ID usada sigue resolviéndose inactiva; nueva asociación exige actividad. No borrar un global con FK actual/histórica.
- Historial de producto global separado de historiales operativos locales; no exponer usos de otras compañías.
- Candidatos y resolución son servicios públicos de Resources; los repositorios y ORM quedan privados.
Justificación: update: resource.aggregate.ts:100 capture: resource-input.mapper.ts:69 softwarePolicy: software-installation-policy.ts:5 applicationPolicy: application-configuration-policy.ts:5 remove: remove-resource.ts:37 service: resource-inventory.service.ts:7.
Duplicación, nombres y unicidad
El UUID es identidad del producto; el nombre no lo sustituye. Mantener regla de nombre por plantilla/contexto dentro de cada ámbito; los nombres iguales entre global y local deben poder coexistir durante adopción. En global, la política de duplicados debe definir qué distingue producto/edición antes de endurecer una unique SQL. Un unique con companyId NULL no asegura nombre global único. Empezar por serialización del catálogo global y validación semántica normalizada existente, con prueba concurrente, sin inventar ID externo.
No fijar stockKey a productos de usuarios: actualmente identifica definiciones de serie. Si se aprueba identificador canónico externo, debe tener namespace, normalización, unicidad e invariantes propios; no apropiarse de un campo libre reference sin contrato.
Decisiones que requieren aprobación
D01 A frente a B y representación de ámbito; D02 allowlist inicial y futuras plantillas elegibles; D03 permiso global y quién lo recibe; D04 modelo de acceso operador–compañía; D05 proyección pública/administrativa de historial y notas; D06 disponibilidad local de globales y plantilla; D07 política de duplicados/ediciones; D08 consolidación y conservación histórica; D09 URLs/endpoints/versionado; D10 activación, rollback y despliegue mixto. Son decisiones para la fase de implementación, no preguntas que bloqueen esta auditoría.