docs(templates): record derive-on-compose decisions (naming, migration, tree UX)

This commit is contained in:
Joseph Doherty
2026-05-12 08:13:11 -04:00
parent 68548432b3
commit a968cefbc2

View File

@@ -243,30 +243,30 @@ Each phase is independently shippable and reviewable.
`ParentTemplateId`, but the UX hasn't been designed.
- Cross-tenant template libraries.
## Open questions
## Decisions
- **Derived-template names**: `Pump.TempSensor` vs `Pump_TempSensor` vs
`${parentName}::${instanceName}`? Visible only on the edit page since the
tree hides derived templates, but appears in audit logs and error messages.
Default: dot-separated mirrors the canonical path format already used in
flattening (`TempSensor.Temperature`). Pick this unless the dot is
problematic for any existing pipeline.
- **Naming**: dot-separated (`Pump.TempSensor`). Matches the canonical-path
format used in flattening. Visible in audit logs / error messages.
- **Delete base with derivatives**: block the delete and list the derivatives.
User must remove or repoint them first.
- **Migration of existing data**: EF Core migration on next startup
auto-derives every existing composition. After deploy all compositions are
derived; no mixed-mode code paths.
- **Tree UX**: derived templates hidden by default. "Show derived templates"
toggle on the tree page reveals them indented under their base. Always
reachable from the parent's Compositions tab.
- **Re-composing the same base in two slots on the same parent**: e.g., Pump
composes Sensor twice as `IntakeSensor` and `OutletSensor`. Two derived
templates: `Pump.IntakeSensor` and `Pump.OutletSensor`. Both inherit from
`Sensor`. Confirmed OK.
## Confirmed semantics
- **Composition order / dependency**: if the user composes A inside B and
later edits A's base — does B's derived template auto-pick up the changes?
Answer per inheritance: yes for `IsInherited = true` fields, no for
overrides. Aveva-consistent.
- **Re-composing the same base on the same parent in two slots** (e.g. Pump
composes Sensor twice as `IntakeSensor` and `OutletSensor`) produces two
derived templates: `Pump.IntakeSensor` and `Pump.OutletSensor`, both
inheriting from `Sensor`.
- **Cascade-delete confirmation**: deleting a base template that has
derivatives — block with a clear error listing the derivatives, force user
to delete them first? Aveva blocks. Likely we should too.
- **Inheritance updates flow downward**: if a base attribute changes value
later and the derivative has `IsInherited = true` for that attribute, the
derived value updates. Once overridden (`IsInherited = false`), changes to
the base no longer affect that field.
- **Validation**: if base adds an attribute, derived inherits it on next load.
But what about derived overriding a field that base subsequently locks via
`LockedInDerived`? Force-revert the override on next deploy? Surface as a
validation error? Probably the latter.
- **Subsequent `LockedInDerived` after overrides exist**: surface as a
validation error at deploy time; do not force-revert silently.