feat(notification-outbox): populate SourceScript on outbound notifications

FU3: thread the executing script identifier from the script-execution
context down to the Notify outbox API so NotifyTarget.Send stamps
NotificationSubmit.SourceScript instead of leaving it null.

- ScriptRuntimeContext / NotifyHelper / NotifyTarget take an optional
  sourceScript value, carried through to NotificationSubmit.SourceScript.
- ScriptExecutionActor supplies "ScriptActor:<scriptName>", matching the
  Site Event Logging "Source" convention used for script error events.
- AlarmExecutionActor builds the context without the S&F engine, so its
  Notify API is inert; sourceScript defaults to null there.
This commit is contained in:
Joseph Doherty
2026-05-19 03:54:09 -04:00
parent a5653b4296
commit 558f9ceb39
3 changed files with 62 additions and 8 deletions

View File

@@ -66,6 +66,15 @@ public class ScriptRuntimeContext
/// </summary>
private readonly string _siteId;
/// <summary>
/// Notification Outbox (FU3): identifier of the script currently executing in this
/// context — stamped onto <c>NotificationSubmit.SourceScript</c> for the central
/// audit trail. Uses the Site Event Logging "Source" convention
/// (<c>"ScriptActor:&lt;scriptName&gt;"</c>). Null when no single script owns the
/// context (e.g. alarm on-trigger paths that do not wire the Notify outbox).
/// </summary>
private readonly string? _sourceScript;
public ScriptRuntimeContext(
IActorRef instanceActor,
IActorRef self,
@@ -79,7 +88,8 @@ public class ScriptRuntimeContext
IDatabaseGateway? databaseGateway = null,
StoreAndForwardService? storeAndForward = null,
ICanTell? siteCommunicationActor = null,
string siteId = "")
string siteId = "",
string? sourceScript = null)
{
_instanceActor = instanceActor;
_self = self;
@@ -94,6 +104,7 @@ public class ScriptRuntimeContext
_storeAndForward = storeAndForward;
_siteCommunicationActor = siteCommunicationActor;
_siteId = siteId;
_sourceScript = sourceScript;
}
/// <summary>
@@ -209,7 +220,7 @@ public class ScriptRuntimeContext
/// <c>Notify.Status(id)</c> queries the delivery status of that notification.
/// </summary>
public NotifyHelper Notify => new(
_storeAndForward, _siteCommunicationActor, _siteId, _instanceName, _askTimeout, _logger);
_storeAndForward, _siteCommunicationActor, _siteId, _instanceName, _sourceScript, _askTimeout, _logger);
/// <summary>
/// Helper class for Scripts.CallShared() syntax.
@@ -356,6 +367,7 @@ public class ScriptRuntimeContext
private readonly ICanTell? _siteCommunicationActor;
private readonly string _siteId;
private readonly string _instanceName;
private readonly string? _sourceScript;
private readonly TimeSpan _askTimeout;
private readonly ILogger _logger;
@@ -364,6 +376,7 @@ public class ScriptRuntimeContext
ICanTell? siteCommunicationActor,
string siteId,
string instanceName,
string? sourceScript,
TimeSpan askTimeout,
ILogger logger)
{
@@ -371,6 +384,7 @@ public class ScriptRuntimeContext
_siteCommunicationActor = siteCommunicationActor;
_siteId = siteId;
_instanceName = instanceName;
_sourceScript = sourceScript;
_askTimeout = askTimeout;
_logger = logger;
}
@@ -381,7 +395,7 @@ public class ScriptRuntimeContext
public NotifyTarget To(string listName)
{
return new NotifyTarget(
listName, _storeAndForward, _siteId, _instanceName, _logger);
listName, _storeAndForward, _siteId, _instanceName, _sourceScript, _logger);
}
/// <summary>
@@ -453,6 +467,7 @@ public class ScriptRuntimeContext
private readonly StoreAndForwardService? _storeAndForward;
private readonly string _siteId;
private readonly string _instanceName;
private readonly string? _sourceScript;
private readonly ILogger _logger;
internal NotifyTarget(
@@ -460,12 +475,14 @@ public class ScriptRuntimeContext
StoreAndForwardService? storeAndForward,
string siteId,
string instanceName,
string? sourceScript,
ILogger logger)
{
_listName = listName;
_storeAndForward = storeAndForward;
_siteId = siteId;
_instanceName = instanceName;
_sourceScript = sourceScript;
_logger = logger;
}
@@ -504,9 +521,10 @@ public class ScriptRuntimeContext
// value is the best-effort site id known to the script runtime.
SourceSiteId: _siteId,
SourceInstanceId: _instanceName,
// SourceScript: the script runtime does not currently thread the script
// name down to the Notify helper; left null until that wiring exists.
SourceScript: null,
// SourceScript (FU3): identifier of the script that raised this
// notification, threaded down from the script-execution context for the
// central audit trail. Null when no single script owns the context.
SourceScript: _sourceScript,
SiteEnqueuedAt: DateTimeOffset.UtcNow);
var payloadJson = JsonSerializer.Serialize(payload);