namespace ZB.MOM.WW.ScadaBridge.Commons.Messages.Management; /// /// Read-only response for : the /// EFFECTIVE inherited member set for a template, computed fresh from the full /// inheritance chain (root → leaf, arbitrary depth) and annotated per member /// with its origin and lock state — plus a staleness summary comparing the /// template's STORED member rows against this freshly-resolved set. /// /// /// /// The precedence used to compute the effective member set MIRRORS /// FlatteningService.ResolveInherited* exactly (derived wins; /// IsInherited placeholders never shadow the live base value; locked /// members flagged), so the editor preview agrees with what a deploy would /// produce. This is the AUTHORING view only — it never mutates stored rows and /// is not on the deploy path. /// /// /// Member values surfaced here are the inheritance-resolved values BEFORE any /// composition or instance override is applied — composition is a separate /// concern owned by the instance flattener, and there are no instances in the /// template-authoring context. /// /// public sealed record ResolvedTemplateMembers { /// The template the member set was resolved for. public int TemplateId { get; init; } /// The template's name. public string TemplateName { get; init; } = string.Empty; /// The immediate parent template id, or null when this is a root template. public int? ParentTemplateId { get; init; } /// The effective resolved attributes (own + transitively inherited). public IReadOnlyList Attributes { get; init; } = []; /// The effective resolved alarms (own + transitively inherited). public IReadOnlyList Alarms { get; init; } = []; /// The effective resolved scripts (own + transitively inherited). public IReadOnlyList Scripts { get; init; } = []; /// The effective resolved native alarm source bindings (own + transitively inherited). public IReadOnlyList NativeAlarmSources { get; init; } = []; /// /// Staleness summary: whether the template's stored member rows differ from /// this freshly-resolved set (e.g. a base member added after the derived /// template was created, or a multi-level inherited member not present in /// the stored rows), and how many inherited members differ. /// public ResolvedTemplateStaleness Staleness { get; init; } = new(); } /// /// One effective member in a set, /// annotated with where its winning definition came from and its lock state. /// public sealed record ResolvedTemplateMemberInfo { /// The member name (bare; inheritance-resolved members are never path-qualified). public string Name { get; init; } = string.Empty; /// /// True when the winning definition lives on an ANCESTOR template rather /// than on the resolved template itself — i.e. this member is inherited. /// public bool IsInherited { get; init; } /// The id of the template that supplied the winning definition. public int OriginTemplateId { get; init; } /// The name of the template that supplied the winning definition. public string OriginTemplateName { get; init; } = string.Empty; /// /// True when the member is locked from override (IsLocked on the /// winning row) — a derived template cannot change it. /// public bool IsLocked { get; init; } /// /// True when an ANCESTOR marked this member LockedInDerived — the /// derived template may not override it (rendered read-only with a lock in /// the editor). Distinct from : a base may forbid /// override (LockedInDerived) without the member itself being a /// locked composition member. /// public bool IsBaseLocked { get; init; } /// /// The effective value for the member, type-appropriate: attribute value, /// script code, alarm priority/trigger summary, or native-source reference. /// Provided so the editor preview shows the live (post-resolution) value /// without re-walking the chain itself. Null when the member type carries /// no single scalar value. /// public string? EffectiveValue { get; init; } /// /// For ALARM members only: the effective (inheritance-resolved) trigger /// configuration JSON — for HiLo alarms this is the per-setpoint MERGED /// config (a derived template overriding only hi inherits the base /// lo), identical to what the flattener produces on deploy, so the /// editor can render the effective HiLo thresholds. Null for non-alarm /// members and for alarms with no trigger configuration. /// public string? EffectiveTriggerConfiguration { get; init; } } /// /// Staleness summary comparing a template's STORED member rows against the /// freshly-resolved inherited member set. /// public sealed record ResolvedTemplateStaleness { /// /// True when the stored derived rows differ from the freshly-resolved set — /// the base changed after the derived template was created, so the editor /// should surface a "base changed" banner. /// public bool IsStale { get; init; } /// /// The number of inherited members whose freshly-resolved state differs /// from what the stored rows reflect (missing rows, added base members, /// changed inherited values). This is the count the editor banner shows. /// public int DifferingMemberCount { get; init; } }