a25593a9c6
Group all 69 projects into category subfolders under src/ and tests/ so the Rider Solution Explorer mirrors the module structure. Folders: Core, Server, Drivers (with a nested Driver CLIs subfolder), Client, Tooling. - Move every project folder on disk with git mv (history preserved as renames). - Recompute relative paths in 57 .csproj files: cross-category ProjectReferences, the lib/ HintPath+None refs in Driver.Historian.Wonderware, and the external mxaccessgw refs in Driver.Galaxy and its test project. - Rebuild ZB.MOM.WW.OtOpcUa.slnx with nested solution folders. - Re-prefix project paths in functional scripts (e2e, compliance, smoke SQL, integration, install). Build green (0 errors); unit tests pass. Docs left for a separate pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
85 lines
3.6 KiB
C#
85 lines
3.6 KiB
C#
namespace ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms;
|
|
|
|
/// <summary>
|
|
/// Persistent per-alarm state tracked by the Part 9 state machine. Every field
|
|
/// carried here either participates in the state machine or contributes to the
|
|
/// audit trail required by Phase 7 plan decision #14 (GxP / 21 CFR Part 11).
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// <see cref="Active"/> is re-derived from the predicate at startup per Phase 7
|
|
/// decision #14 — the engine runs every alarm's predicate against current tag
|
|
/// values at <c>Load</c>, overriding whatever Active state is in the store.
|
|
/// Every other state field persists verbatim across server restarts so
|
|
/// operators don't re-ack active alarms after an outage + shelved alarms stay
|
|
/// shelved + audit history survives.
|
|
/// </para>
|
|
/// <para>
|
|
/// <see cref="Comments"/> is append-only; comments + ack/confirm user identities
|
|
/// are the audit surface regulators consume. The engine never rewrites past
|
|
/// entries.
|
|
/// </para>
|
|
/// </remarks>
|
|
public sealed record AlarmConditionState(
|
|
string AlarmId,
|
|
AlarmEnabledState Enabled,
|
|
AlarmActiveState Active,
|
|
AlarmAckedState Acked,
|
|
AlarmConfirmedState Confirmed,
|
|
ShelvingState Shelving,
|
|
DateTime LastTransitionUtc,
|
|
DateTime? LastActiveUtc,
|
|
DateTime? LastClearedUtc,
|
|
DateTime? LastAckUtc,
|
|
string? LastAckUser,
|
|
string? LastAckComment,
|
|
DateTime? LastConfirmUtc,
|
|
string? LastConfirmUser,
|
|
string? LastConfirmComment,
|
|
IReadOnlyList<AlarmComment> Comments)
|
|
{
|
|
/// <summary>Initial-load state for a newly registered alarm — everything in the "no-event" position.</summary>
|
|
public static AlarmConditionState Fresh(string alarmId, DateTime nowUtc) => new(
|
|
AlarmId: alarmId,
|
|
Enabled: AlarmEnabledState.Enabled,
|
|
Active: AlarmActiveState.Inactive,
|
|
Acked: AlarmAckedState.Acknowledged,
|
|
Confirmed: AlarmConfirmedState.Confirmed,
|
|
Shelving: ShelvingState.Unshelved,
|
|
LastTransitionUtc: nowUtc,
|
|
LastActiveUtc: null,
|
|
LastClearedUtc: null,
|
|
LastAckUtc: null,
|
|
LastAckUser: null,
|
|
LastAckComment: null,
|
|
LastConfirmUtc: null,
|
|
LastConfirmUser: null,
|
|
LastConfirmComment: null,
|
|
Comments: []);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Shelving state — kind plus, for <see cref="ShelvingKind.Timed"/>, the UTC
|
|
/// timestamp at which the shelving auto-expires. The engine polls the timer on its
|
|
/// evaluation cadence; callers should not rely on millisecond-precision expiry.
|
|
/// </summary>
|
|
public sealed record ShelvingState(ShelvingKind Kind, DateTime? UnshelveAtUtc)
|
|
{
|
|
public static readonly ShelvingState Unshelved = new(ShelvingKind.Unshelved, null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// A single append-only audit record — acknowledgement / confirmation / explicit
|
|
/// comment / shelving action. Every entry carries a monotonic UTC timestamp plus the
|
|
/// user identity Phase 6.2 authenticated.
|
|
/// </summary>
|
|
/// <param name="TimestampUtc">When the action happened.</param>
|
|
/// <param name="User">OS / LDAP identity of the actor. For engine-internal events (shelving expiry, startup recovery) this is <c>"system"</c>.</param>
|
|
/// <param name="Kind">Human-readable classification — "Acknowledge", "Confirm", "ShelveOneShot", "ShelveTimed", "Unshelve", "AddComment", "Enable", "Disable", "AutoUnshelve".</param>
|
|
/// <param name="Text">Operator-supplied comment or engine-generated message.</param>
|
|
public sealed record AlarmComment(
|
|
DateTime TimestampUtc,
|
|
string User,
|
|
string Kind,
|
|
string Text);
|