Entity model
Los dispositivos por sí solos son una lista plana. El entity model es la forma en que CORE-M les da estructura y los comparte de forma segura: los activos agrupan y ubican dispositivos, las relations tipadas conectan todo en un grafo navegable, y los clientes obtienen acceso de subtenant estrechamente acotado mediante entity views y asignaciones de dashboard.
Todo lo de aquí está acotado al tenant y se almacena en el namespace de Aerospike
devices.
Activos
Sección titulada «Activos»Un activo es una entity de primera clase que representa una agrupación lógica o física
— un sitio, edificio, línea de producción, máquina, vehículo o medidor. Los activos viven
en devices/assets, con clave {tenant_id}:{asset_id}, y contienen name, type,
label, tags, metadata, status y version.
- Nombre único por tipo por tenant. Crear un segundo
sitellamado “Factory 1” en un tenant que ya tiene uno se rechaza conALREADY_EXISTS(y no se publica ningún evento). El mismo nombre bajo un tipo distinto está permitido. - Consultable por tipo y tag. Puedes listar activos filtrados por tipo y tag (p. ej.
type=site,region=eu), paginados connext_page_token. - Soft delete. Eliminar un activo establece
status="deleted"; queda excluido de las listas normales pero se conserva para auditoría y es recuperable coninclude_deleted=true, que devuelvedeleted_atydeleted_by.
Crear un activo publica entity.asset.created.T1.{asset_id} y escribe un audit event.
Relations dirigidas tipadas
Sección titulada «Relations dirigidas tipadas»Las relations conectan entidades — dispositivos, activos, clientes, dashboards y entity
views — en un grafo dirigido. Cada relation tiene un type y una dirección, almacenada
en devices/relations con clave
{tenant_id}:{from_type}:{from_id}:{relation_type}:{to_type}:{to_id}.
| Tipo de relation | Uso típico |
|---|---|
contains | Un activo contiene subactivos o dispositivos |
manages | Una entity gestiona otra |
assigned_to | Un dashboard asignado a un cliente/usuario |
located_at | Un dispositivo ubicado en un activo |
monitors | Un dispositivo monitorea un target |
depends_on | Una arista de dependencia entre entidades |
Crear A1 --contains--> D1 escribe un registro de relation, construye índices de búsqueda
inversa (para que puedas consultar “dispositivos contenidos por A1”) y publica
entity.relation.created.T1.A1.D1.
Prevención de ciclos
Sección titulada «Prevención de ciclos»Para los tipos de relation donde los ciclos están prohibidos (como una jerarquía
contains), el sistema rechaza las aristas que cerrarían un bucle. Si A1 contains A2, un
intento de crear A2 --contains--> A1 se rechaza con FAILED_PRECONDITION y la respuesta
identifica la ruta del ciclo, para que puedas ver exactamente qué aristas entran en
conflicto.
Recorrido de jerarquía
Sección titulada «Recorrido de jerarquía»Las relations son navegables en ambas direcciones y a lo largo de la profundidad. Pedir
los descendientes de A1 filtrados a entity_type=device — dado A1 contains A2 y
A2 contains D1, D2 — devuelve D1 y D2, cada uno con su ruta de relation de vuelta
a A1. Esa ruta es lo que los dashboards y los nodos de enriquecimiento usan para
renderizar y razonar sobre la jerarquía.
flowchart TD A1["Asset: Factory 1<br/>(site)"] -->|contains| A2["Asset: Line A<br/>(line)"] A1 -->|contains| A3["Asset: Line B<br/>(line)"] A2 -->|contains| D1["Device: Boiler 1"] A2 -->|contains| D2["Device: Boiler 2"] A3 -->|contains| D3["Device: Press 1"] D1 -.located_at.-> A2
Clientes y usuarios de cliente
Sección titulada «Clientes y usuarios de cliente»Un cliente es una entity acotada al tenant que recibe acceso restringido — piensa
en un cliente final de tu tenant que solo debería ver su propio equipamiento, nunca todo
el tenant. Los clientes viven en devices/customers con clave {tenant_id}:{customer_id}.
Los usuarios de cliente son usuarios de autenticación con autoridad customer_user y
una o más membresías de cliente. Su acceso es fundamentalmente más estrecho que el de un
member:
Invitar a un usuario de cliente crea un usuario de autenticación con
authority="customer_user", lo asigna al cliente, y audita la invitación.
Entity views
Sección titulada «Entity views»Un entity view es el mecanismo que otorga a un cliente acceso a una porción específica
de los datos de una entity — y nada más. Los views viven en devices/entity_views con
clave {tenant_id}:{view_id} y contienen entity_type, entity_id, customer_id,
field_mask, telemetry_key_allowlist, start_time, end_time y version.
Tres controles definen la porción:
field_mask— qué campos de la entity son visibles. Un view que enmascara la configuración y la clave de API significa que un cliente que lee el dispositivoD1a través de él no ve configuración, ni clave de API, ni credenciales, ni metadatos internos, ni claves de telemetry no relacionadas.telemetry_key_allowlist— qué métricas son legibles. Un view que permite["temperature", "humidity"]deja que el cliente consulte solo esas claves para el dispositivo.start_time/end_time— la ventana de validez.
Compartición y revocación de dashboards
Sección titulada «Compartición y revocación de dashboards»Los dashboards se pueden asignar a clientes (y usuarios) con permiso view o edit
mediante una relation assigned_to.
-
Asignar. Asignar el dashboard
DB1al clienteC1conpermission="view"creaDB1 --assigned_to--> C1. Los usuarios de cliente deC1ahora venDB1en su lista pero no pueden editarlo. -
Revocar. Revocar elimina la relation. Las sesiones WebSocket activas de
C1reciben de inmediato un eventodashboard_access_revoked, y las lecturas posteriores de la API de dashboard devuelvenPERMISSION_DENIED.
Así que la revocación es en tiempo real: un visor en curso no mantiene el dashboard abierto hasta que refresque — a su sesión en vivo se le indica que pierda el acceso de inmediato.
Soft delete y auditoría
Sección titulada «Soft delete y auditoría»Los activos, clientes, relations y entity views admiten todos soft delete con
historial de auditoría. Eliminar un cliente es el caso más amplio: establece
status="deleted", deshabilita las asignaciones y entity views del cliente, retira el
acceso del usuario de cliente en su siguiente petición, y escribe un audit event que
enumera los entity_view_ids y dashboard_ids deshabilitados. Las entidades eliminadas
se conservan para auditoría y se excluyen de las consultas de lista por defecto.
Cómo se conecta todo
Sección titulada «Cómo se conecta todo»flowchart LR cust["Customer C1"] -->|has| cu["Customer user CU1"] ev["Entity view EV1<br/>field_mask + allowlist + expiry"] -->|customer_id| cust ev -->|entity_id| dev["Device D1"] db["Dashboard DB1"] -->|assigned_to| cust cu -.reads through.-> ev cu -.sees.-> db
Un usuario de cliente alcanza datos únicamente a lo largo de estas aristas: a través de un entity view que nombra a su cliente y un dispositivo, o a través de un dashboard asignado a su cliente. Cualquier cosa fuera de esa ruta se deniega.