namespace ZB.MOM.WW.OtOpcUa.Commons.Messages.Alerts;

/// <summary>
/// Live alarm transition published on the cluster <c>alerts</c> DistributedPubSub topic.
/// Emitted by ScriptedAlarmActor (and future native-alarm bridges) when an alarm condition
/// transitions; consumed by <c>AlertSignalRBridge</c> for browser fan-out and by historian
/// adapters for durable storage.
/// </summary>
/// <param name="AlarmId">Stable condition identity (matches <c>ScriptedAlarm.ScriptedAlarmId</c> for scripted alarms).</param>
/// <param name="EquipmentPath">UNS path of the Equipment node the alarm hangs under. Doubles as the SourceNode.</param>
/// <param name="AlarmName">Operator-visible alarm name.</param>
/// <param name="TransitionKind">Activated / Cleared / Acknowledged / Confirmed / Shelved / Unshelved / Disabled / Enabled / CommentAdded.</param>
/// <param name="Severity">1–1000 numeric severity (OPC UA convention).</param>
/// <param name="Message">Fully-rendered message text — template tokens already resolved.</param>
/// <param name="User">Operator who triggered the transition. "system" for engine-driven events.</param>
/// <param name="TimestampUtc">When the transition occurred.</param>
/// <param name="AlarmTypeName">OPC UA Part 9 condition subtype name — one of <c>LimitAlarm</c> / <c>DiscreteAlarm</c> / <c>OffNormalAlarm</c> / <c>AlarmCondition</c> (the base type, used as the default). The historian feed maps this onto the durable alarm-type column.</param>
/// <param name="Comment">Operator-supplied comment on ack / confirm / comment transitions; <c>null</c> for engine-driven transitions (Activated / Cleared / Shelved / …) that carry no comment.</param>
/// <param name="HistorizeToAveva">When <c>false</c>, the durable historian sink suppresses this transition (the live <c>alerts</c> fan-out is unaffected); <c>null</c> or <c>true</c> historize. <c>null</c> is the cross-version/rolling-restart case: an old-format message missing the field deserializes to <c>null</c> (CLR default for <c>bool?</c>) and is historized (safe default-on), matching the <c>AlarmTypeName</c> null-coalesce in <c>HistorianAdapterActor.Translate</c>. The producer (<c>ScriptedAlarmHostActor</c>) always sets a concrete <c>true</c>/<c>false</c>.</param>
/// <param name="ReferencingEquipmentPaths">v3 Batch 4 (multi-notifier native alarms) — the (possibly empty) list of UNS equipment-folder paths (<c>Area/Line/Equipment</c>) that reference the alarm's backing raw tag. A native alarm is a SINGLE Part 9 condition materialised once at the raw tag (its <see cref="AlarmId"/> is the RawPath); the same condition fans events to every referencing equipment's UNS folder via SDK notifiers, and this list is carried so <c>/alerts</c> shows the one condition row with all its referencing equipment as display metadata. Empty for scripted alarms (they are per-equipment) and for a native alarm whose raw tag no equipment references. Defaults empty so every existing producer + rolling-restart deserialization keeps compiling / working.</param>
public sealed record AlarmTransitionEvent(
    string AlarmId,
    string EquipmentPath,
    string AlarmName,
    string TransitionKind,
    int Severity,
    string Message,
    string User,
    DateTime TimestampUtc,
    string AlarmTypeName = "AlarmCondition",
    string? Comment = null,
    bool? HistorizeToAveva = null,
    IReadOnlyList<string>? ReferencingEquipmentPaths = null);
