When the user composes a template that already has compositions of its own (e.g. \$Sensor → Probe1 slot), only the outer derived was created — the source's children weren't replicated. AddCompositionAsync now walks the source's composition graph and creates a parallel derived for every slot it encounters, each linked back through ParentTemplateId so override chains stay intact (\$Probe → \$Sensor.Probe1 → \$Pump.TempSensor.Probe1). The cascade pre-flights every name it would create — a deep collision aborts before any rows mutate. Internal helper CreateCascadedCompositionAsync skips the "base templates only" check since it operates on the source side which may legitimately reference derived rows.
39 KiB
39 KiB