metis-desk/docs/arquitectura/modelo-ddd-e-identificadores.md
David 7a83f9780e feat: implement access management features including forms, history, and labels
- Added access fields definition in access-fields.ts
- Created access form values handling in access-form-values.ts
- Developed access form component for creating and editing access items
- Implemented access history dialog to view changes made to access items
- Introduced access labels for better representation of access items
- Built access row component for displaying access items in a table
- Created access workspace page for managing access items with search functionality
- Added internationalization support for Spanish and English languages
- Implemented tests for access components to ensure functionality
2026-10-03 15:19:20 +02:00

51 lines
5.5 KiB
Markdown

# Modelo DDD e identificadores
## Regla de identidad
Toda entidad de negocio de Metis Desk, tanto raíz de agregado como entidad interna, tiene un identificador global único UniqueID. Se genera como UUID v7, igual que en factuges-erp. Clientes, personas, departamentos, asignaciones, revisiones, sedes/ubicaciones, documentos, tickets, intervenciones, assets, contratos y las demás entidades seguirán esta regla.
La identidad no depende de nombres, correos, referencias visibles ni claves numéricas incrementales. No cambia al actualizar, activar o archivar. Las relaciones entre entidades usan el UniqueID de la entidad referenciada.
Los UUID anteriores válidos, incluidos los v4 de usuarios ya creados, se conservan al leer y escribir. No se reasignan identificadores ni se reescriben relaciones. UniqueID.create valida un identificador recibido; UniqueID.generateNewID genera uno nuevo.
Los identificadores viajan como cadenas UUID en DTOs y se validan con z.uuid. Dentro del dominio y de los puertos de repositorio se usa UniqueID, no string. Infrastructure convierte a la representación persistida. La clave primaria y las claves foráneas se declaran explícitamente en las migraciones.
El marcador técnico de configuración y el identificador opaco de cookie de express-session no representan entidades de negocio y mantienen sus contratos de infraestructura.
## Declaraciones
packages/rdx-ddd proporciona la base compartida, independiente del filesystem del ERP:
- ValueObject: valor escalar inmutable e igualdad semántica por valor y tipo. Los Value Objects no tienen identidad.
- UniqueID, Name y EmailAddress: Value Objects compartidos con create, getProps, toPrimitive, toString y equals.
- DomainEntity: identidad UniqueID y propiedades de dominio. La igualdad se basa en identidad y tipo, independientemente de los atributos.
- AggregateRoot: entidad que delimita una unidad de consistencia y es persistida por su repositorio.
La dependencia uuid 13 se usa para generar UUID v7, como en el ERP; se evita implementar un generador propio.
Se conserva la organización y los nombres del ERP, con tipos estrictos y sin copiar sus dependencias o utilidades no utilizadas. Esta base escalar no introduce comparación genérica de objetos compuestos ni un bus de eventos sin consumidores.
Las raíces se declaran en archivos *.aggregate.ts; las entidades internas en *.entity.ts. Los Value Objects específicos de un módulo viven en domain/value-objects. Domain permanece libre de Express, DTOs de transporte y Sequelize. La validación propia de los Value Objects puede usar Zod, igual que en el ERP.
## Ciclo de vida y fronteras
create valida invariantes de creación y devuelve Result. La nueva raíz genera su UniqueID cuando no recibe uno explícito. rehydrate exige el ID persistido, no genera otro y no aplica reglas de alta ni emite eventos. update aplica invariantes de actualización y compara valores con equals.
En esta entrega los agregados devuelven una instancia nueva al cambiar; una actualización semánticamente idéntica devuelve la misma instancia. Todas conservan el UniqueID original.
Application adapta DTOs a Value Objects mediante InputMapper. Los errores de entrada esperados se devuelven como Result. Los repositorios aceptan identificadores y valores de dominio.
Infrastructure reconstruye los Value Objects mediante create antes de llamar a rehydrate. Un valor persistido inválido provoca un error de consistencia sin incluir datos sensibles; no se oculta ni se reemplaza por un valor generado. toPersistence serializa primitivas. Los builders HTTP también serializan primitivas y solo exponen los campos previstos por el DTO.
## Aplicación actual y siguientes módulos
User es la raíz del agregado de identidad. Sus Value Objects son UniqueID, Name, EmailAddress y PasswordHash. Conserva las invariantes del administrador inicial, la activación y la invalidación de sesiones.
Company es la raíz del agregado de compañías clientes. Person, Department, DepartmentAssignment y Site son entidades internas con UniqueID propio y referencia UniqueID a su compañía. AssignmentRevision conserva cada versión de una asignación y tiene su propio UniqueID. Los contactos son personas con isContact=true. Name, EmailAddress, PhoneNumber, CalendarDate y SiteAddress representan sus valores; los campos opcionales usan Maybe. Las reglas de pertenencia, periodos y departamento principal se resuelven dentro de Company. El repositorio carga y guarda el agregado completo dentro de una transacción con bloqueo de la compañía.
AccessWorkspace es una raíz adicional para el catálogo global o la configuración informática de una compañía. Cada espacio conserva su propio UUID. AccessItem y AccessRevision son entidades con UUID propio. AccessValues encapsula la definición tipada e inmutable, con identificadores y fechas reconstruidos como UniqueID y CalendarDate. Las referencias relacionales preservan las dependencias y el historial conserva el actor autenticado. Consultar [Cuentas, grupos y recursos](../cuentas-grupos-y-recursos.md).
Los módulos de documentos, tickets y assets todavía no existen. Se declararán como agregados o entidades al implementar sus operaciones y reglas de consistencia. La decisión de pertenencia a un agregado se toma por sus invariantes y transacciones; no convierte automáticamente cada tabla en una raíz ni fuerza todo el cliente y sus tickets dentro de un solo agregado.
Cada entidad que se incorpore deberá tener UniqueID desde su primera implementación, mapper de persistencia y pruebas de identidad, invariantes, rehidratación y actualización.