fix(alarms): SDK timed-unshelve timer is a no-op; commented re-ack comment is durable (#597)
Review R1 M2: since #597 the SDK timer fires at real expiry, and OnTimedUnshelve routed an operator-style Unshelve by 'system' from both pair nodes, pre-empting the engine's AutoUnshelve. The engine owns expiry, so the callback now routes nothing. Integration test: an engine stand-in that acts on a routed Unshelve and expires late, plus a wrapped OnTimedUnshelve (positive control: the SDK timer fired). Review R1 m1: Part9StateMachine.ApplyAcknowledge records a commented re-ack as AddComment (persisted and replicated) instead of a NoOp; an uncommented re-ack is still a no-op. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -105,7 +105,17 @@ public static class Part9StateMachine
|
||||
throw new ArgumentException("User identity required for audit.", nameof(user));
|
||||
|
||||
if (current.Acked == AlarmAckedState.Acknowledged)
|
||||
return TransitionResult.NoOp(current, "already acknowledged");
|
||||
{
|
||||
// A COMMENTED re-ack carries a real comment even though nothing is acknowledged (Gitea #597 review
|
||||
// m1): the OPC UA node reports it — the SDK writes the comment on a re-ack — so the system of
|
||||
// record must hold it too, or the event advertises a comment that exists only on the node that
|
||||
// served the call (never persisted, never replicated to the pair peer). Recorded exactly like
|
||||
// AddComment; the ack fields (LastAck*) stay those of the real acknowledge. An uncommented re-ack
|
||||
// is still a no-op.
|
||||
return string.IsNullOrWhiteSpace(comment)
|
||||
? TransitionResult.NoOp(current, "already acknowledged")
|
||||
: ApplyAddComment(current, user, comment, nowUtc);
|
||||
}
|
||||
|
||||
var audit = AppendComment(current.Comments, nowUtc, user, "Acknowledge", comment);
|
||||
var next = current with
|
||||
|
||||
Reference in New Issue
Block a user