> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prodexlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Nodos de modelo y modelado jerárquico

> Incrusta un modelo dentro de otro para construir submodelos reutilizables y escalar a simulaciones a nivel de instalación.

## Visión general

Un **Nodo de modelo (Model Node)** es un componente que incrusta otro modelo de simulación dentro del actual. En lugar de duplicar componentes entre muchos modelos, defines un submodelo una vez (una celda de producción, una línea de ensamblaje, un departamento) y lo incrustas donde lo necesites. Los cambios al submodelo se propagan a todas partes donde se usa.

Esta es la arquitectura para instalaciones complejas: modela una sola celda rigurosamente, compón un departamento a partir de copias de esa celda, compón una instalación a partir de copias del departamento. Sin modelado jerárquico, una operación compleja significa miles de componentes en un solo lienzo. Con él, obtienes una descomposición limpia que refleja cómo está realmente organizada tu operación.

## Cuándo usar Nodos de modelo

* **Estructura física repetida**: tu instalación tiene cinco celdas de producción idénticas. Modela una, luego incrústala cinco veces vía Nodos de modelo.
* **Plantillas (Template) reutilizables**: subprocesos estándar (inspección de QC, empaque, kitting) que aparecen en muchos modelos. Define una vez, reutiliza entre modelos e incluso entre fábricas vía export/import.
* **Escala**: una vez que un modelo supera \~50-100 componentes, la descomposición jerárquica se convierte en la única forma de mantenerlo navegable.
* **División del equipo**: una persona es dueña del submodelo a nivel de línea, otra es dueña de la composición a nivel de instalación. Los Nodos de modelo les permiten trabajar en paralelo.

## Cómo se añade un Nodo de modelo

Un Nodo de modelo es una referencia a un modelo separado que ya existe en la misma fábrica. Para añadir uno al modelo actual:

1. Abre el panel izquierdo del Modelador (Modeler) y permanece en la pestaña **Library**.
2. Desplázate a la subsección **MODELS** en la parte inferior del panel.
3. Haz clic en **+ Import Model** para abrir un selector que lista los otros modelos de la fábrica. Seleccionar uno añade el slug del modelo a la lista `imported_models[]` del padre y lo expone como una tarjeta arrastrable en la subsección MODELS.
4. Arrastra la tarjeta al lienzo. Aparece un Nodo de modelo, haciendo referencia a ese submodelo.

<Warning>
  **El padre debe listar el submodelo en `imported_models[]` antes de que un Nodo de modelo que lo referencie pueda validar.** Esa lista es la puerta: sin ella, el `nested_model_id` del ModelNode no se resuelve y el modelo falla la validación. *+ Import Model* gestiona esta lista automáticamente cuando lo usas, pero si autorizas el JSON a mano debes añadir el slug tú mismo.
</Warning>

## Campos del esquema

Un ModelNode es un objeto de referencia delgado: la mayor parte de lo que hace vive en el submodelo. Los campos obligatorios son escasos; todo lo demás es opcional y por defecto está vacío.

| Campo                     | Obligatorio | Propósito                                                                                                                          |
| ------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `id`                      | sí          | Id del componente (usado en rutas calificadas, `element_id` del calendario, columnas de dataset)                                   |
| `nested_model_id`         | sí          | Slug del submodelo. Debe aparecer en el `imported_models[]` del padre.                                                             |
| `name`                    | no          | Nombre para mostrar (por defecto, el id)                                                                                           |
| `description`             | no          | Texto libre                                                                                                                        |
| `component_type`          | no          | Constante `"model_node"` (auto-establecido por defecto)                                                                            |
| `input_mappings`          | no          | Lista de pares `{external_connection_id, internal_component_id}`: conecta las conexiones del padre a los componentes del submodelo |
| `output_mappings`         | no          | Misma forma: conecta los componentes del submodelo a las conexiones del padre                                                      |
| `resource_mappings`       | no          | Mapa de alias por recurso; los recursos no mapeados permanecen locales                                                             |
| `topic_mappings`          | no          | Mapa de alias por tema; puentea padre ↔ submodelo bidireccionalmente                                                               |
| `state_variable_mappings` | no          | Mapa de alias por variable de estado; puentea lectura/escritura bidireccionalmente                                                 |
| `event_listeners`         | no          | Oyentes basados en tema en el propio ModelNode                                                                                     |
| `event_hooks`             | no          | El esquema acepta el campo, pero no hay eventos canónicos de ciclo de vida definidos para ModelNodes, ver abajo                    |

`additionalProperties: false`. No se permiten otros campos.

## Conexiones mapeadas

`input_mappings` y `output_mappings` son la capa de cableado: cada entrada empareja un `external_connection_id` (una conexión en el lienzo del padre) con un `internal_component_id` (un componente dentro del submodelo). Cuando el flujo del padre alcanza un mapeo de entrada, las entidades fluyen hacia el componente del submodelo nombrado; cuando se dispara un mapeo de salida, las entidades cruzan de vuelta hacia fuera.

Puedes cambiar la estructura interna del submodelo sin romper al padre: siempre que los mapeos aún se resuelvan a componentes válidos dentro, el modelo padre sigue funcionando.

## Recursos compartidos

Un [Recurso (Resource)](/es/product/simulation-modeling#component-types) puede compartirse entre un padre y un submodelo introduciendo una entrada explícita `resource_mappings` que aliase un id de recurso del padre al nombre esperado del submodelo. **Los recursos no mapeados permanecen locales al submodelo**: si no lo mapeas, el submodelo usa su propio recurso de ese nombre.

Usa recursos compartidos para operadores o equipos que físicamente sirven a múltiples celdas.

## Temas puenteados

Los [Temas (Topics)](/es/reference/events#topics) pueden puentearse a través del límite padre/hijo vía `topic_mappings`. El puenteo es **siempre bidireccional**: no hay configuración por dirección, y el validador construye automáticamente la prevención de bucles en el grafo de temas. Un evento emitido dentro del submodelo en un tema puenteado se recibe en el padre, y viceversa.

## Variables de estado aliasadas

Las [Variables de estado](/es/reference/events#state-variables) pueden aliasarse: una variable de estado declarada a nivel del padre puede referenciarse desde dentro del submodelo bajo un nombre diferente vía `state_variable_mappings`. El aliasing es **lectura/escritura bidireccional**: ambos lados ven y escriben el mismo valor subyacente, con el validador imponiendo tipos coincidentes en ambos extremos.

Esto mantiene los submodelos desacoplados (hacen referencia a sus propios nombres internos) mientras aún les permite participar en el estado a nivel del padre.

## Las constantes y tablas de búsqueda no necesitan mapeo

Las [Constantes](/es/reference/constants-and-lookups) y tablas de búsqueda están **limitadas a la fábrica**. Tanto el padre como el submodelo las referencian por slug independientemente: no hay capa de aliasing para estas en un ModelNode. Cada modelo tiene su propia lista de opt-in (`constants[]` / `lookup_tables[]` en `metadata.json`); ambos pueden optar por participar en la misma constante a nivel de fábrica sin coordinación.

## Rutas calificadas de componentes

Los componentes dentro de un Nodo de modelo se direccionan mediante una **ruta calificada** usando `::` como separador. Un componente con id `lathe` dentro de un ModelNode con id `cell_a` se referencia como `cell_a::lathe` en cualquier lugar fuera de su submodelo padre, la misma forma que verás en SQL de fuente de la vista del Chart, `element_id` de calendarios y columnas de dataset.

Todos los segmentos son **slugs** de componente, no nombres para mostrar. El separador `::` está reservado: ningún id de componente individual puede contenerlo.

Esto se aplica en tres lugares:

* **Consultas de fuente de la vista del Chart.** Los identificadores de componentes en `entity_lifecycle`, `process_activity` y otros [dataframes](/es/product/results-and-analytics#available-dataframes) usan la forma calificada. Filtrar por nombre para mostrar como aparece en el Modelador (digamos, `component = 'Lathe'`) omite cada instancia dentro de un Nodo de modelo. Usa `component = 'cell_a::lathe'`, o coincide con `LIKE`.
* **Liberaciones de material del calendario.** Una liberación de material programada a una Fuente (Source) dentro de un submodelo debe nombrar la Fuente con su id calificado: `cell_a::raw_material_intake`.
* **Referencias cruzadas en funciones de consulta de componentes del DSL**: pasa el id calificado cuando el componente que estás consultando vive en un submodelo.

Autorizar hooks y listeners *dentro* del submodelo usa ids de componente **locales**: el prefijo calificado solo se necesita al cruzar el límite padre-hijo. Los submodelos permanecen reutilizables; no necesitan saber qué nombre les dio su padre.

Para estructuras profundamente anidadas, las rutas se encadenan: `plant_1::line_3::cell_2::lathe`.

## Soporte del Sistema de Eventos en ModelNode

Los ModelNodes pueden llevar **Event Listeners** (basados en tema) y funcionan completamente: escucha cualquier tema en el padre o puenteado al submodelo, y ejecuta `assign` / `emit` / etc. como cualquier otro listener. Útil para coordinación a nivel de ModelNode que no esté vinculada a un solo componente interno.

Los ModelNodes también aceptan un arreglo `event_hooks[]` en el esquema, pero **no hay eventos canónicos de ciclo de vida definidos para ModelNodes**, cualquier hook que autorices no tiene un valor de evento válido y fallará la validación. Cíñete a los listeners.

## La validación se recurre a través de los límites

Cuando validas el modelo padre, la validación se recurre en cada modelo anidado referenciado por un ModelNode. Los errores dentro de un submodelo burbujean al padre con un prefijo de ruta, por ejemplo:

> *"Nested model 'cell\_a' (used by model node 'fab\_cell'): Process 'lathe' has expression error in processing\_time..."*

Arregla el error en el archivo del submodelo; el padre se revalida automáticamente.

## Referencia en vivo, no instantánea

Un ModelNode referencia su submodelo por slug. Cualquier cambio que hagas al archivo del submodelo se refleja inmediatamente en cada ModelNode que lo referencia, no hay anclaje de instantánea a nivel de ModelNode. Si necesitas congelar una revisión específica de un submodelo, captura una [Instantánea (Snapshot)](/es/reference/snapshots) del padre (que incrusta el registro completo del modelo en ese momento).

## Patrones comunes

**Plantilla de celda.** Un submodelo "celda de producción" se crea una vez con equipo canónico. El modelo de instalación lo instancia cinco veces vía Nodos de modelo, cada uno apuntando al mismo slug de submodelo.

**Composición de departamento.** Construye un modelo "fabricación" y un modelo "ensamblaje" por separado, luego compónlos en un modelo de instalación con conexiones entre sus salidas y entradas.

**Detalle progresivo.** Comienza con un modelo de instalación grueso, unos pocos Nodos de modelo, cada uno representando un departamento como una caja negra. A medida que necesitas más fidelidad, reemplaza la referencia de submodelo de un Nodo de modelo por una más detallada. El padre no cambia.

## Consejos

* **Trata los submodelos como bibliotecas.** Una vez que un submodelo es estable, evita editarlo casualmente: los cambios se propagan a cada instancia.
* **Nombra las entradas y salidas claramente.** Los ids de mapeo coinciden por nombre; los nombres claros previenen errores de cableado.
* **Mantén el nivel superior delgado.** Un modelo de instalación bien organizado es principalmente Nodos de modelo con un poco de pegamento entre ellos. Si tu nivel superior tiene cientos de componentes directos, estás perdiendo el beneficio.
* **Todos los segmentos de ruta son slugs.** Cuando dudes sobre un id, verifica el esquema o las columnas del dataset: los nombres para mostrar con espacios no aparecen en las rutas `::`.
