diff --git a/src/ZB.MOM.WW.ScadaBridge.Commons/Messages/Notification/NotificationOutboxQueries.cs b/src/ZB.MOM.WW.ScadaBridge.Commons/Messages/Notification/NotificationOutboxQueries.cs
index 45803fa3..7c25b2f0 100644
--- a/src/ZB.MOM.WW.ScadaBridge.Commons/Messages/Notification/NotificationOutboxQueries.cs
+++ b/src/ZB.MOM.WW.ScadaBridge.Commons/Messages/Notification/NotificationOutboxQueries.cs
@@ -6,6 +6,11 @@ namespace ZB.MOM.WW.ScadaBridge.Commons.Messages.Notification;
/// Outbox UI -> Central: paginated, filtered query over the notification outbox.
/// All filter fields are optional; restricts results to stuck notifications.
///
+///
+/// Exact match on a single notification — the ?correlationId= deep link from the
+/// Flow Debugger / Audit Log. Additive; null means "no filter" (legacy senders
+/// compile unchanged).
+///
public record NotificationOutboxQueryRequest(
string CorrelationId,
string? StatusFilter,
@@ -18,7 +23,8 @@ public record NotificationOutboxQueryRequest(
DateTimeOffset? To,
int PageNumber,
int PageSize,
- string? SourceNodeFilter = null);
+ string? SourceNodeFilter = null,
+ string? NotificationIdFilter = null);
///
/// A single notification row summarised for outbox UI display.
diff --git a/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Notifications/NotificationOutboxFilter.cs b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Notifications/NotificationOutboxFilter.cs
index 2d27ab42..307bd732 100644
--- a/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Notifications/NotificationOutboxFilter.cs
+++ b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Notifications/NotificationOutboxFilter.cs
@@ -23,6 +23,10 @@ namespace ZB.MOM.WW.ScadaBridge.Commons.Types.Notifications;
/// "central-a", "site-plant-a-node-a"). Exact match; null
/// means "do not constrain".
///
+///
+/// Exact match on a single NotificationId — the ?correlationId= deep link
+/// from the Flow Debugger / Audit Log. null means "do not constrain".
+///
public record NotificationOutboxFilter(
NotificationStatus? Status = null,
NotificationType? Type = null,
@@ -33,4 +37,5 @@ public record NotificationOutboxFilter(
DateTimeOffset? StuckCutoff = null,
DateTimeOffset? From = null,
DateTimeOffset? To = null,
- string? SourceNode = null);
+ string? SourceNode = null,
+ string? NotificationId = null);
diff --git a/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/NotificationOutboxRepository.cs b/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/NotificationOutboxRepository.cs
index f005c08e..b3f5af4a 100644
--- a/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/NotificationOutboxRepository.cs
+++ b/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/NotificationOutboxRepository.cs
@@ -280,6 +280,12 @@ VALUES
query = query.Where(n => n.Type == type);
}
+ // Exact match on one notification — the ?correlationId= deep link.
+ if (!string.IsNullOrEmpty(filter.NotificationId))
+ {
+ query = query.Where(n => n.NotificationId == filter.NotificationId);
+ }
+
if (!string.IsNullOrEmpty(filter.SourceSiteId))
{
query = query.Where(n => n.SourceSiteId == filter.SourceSiteId);
diff --git a/src/ZB.MOM.WW.ScadaBridge.NotificationOutbox/NotificationOutboxActor.cs b/src/ZB.MOM.WW.ScadaBridge.NotificationOutbox/NotificationOutboxActor.cs
index f478aef3..412053b5 100644
--- a/src/ZB.MOM.WW.ScadaBridge.NotificationOutbox/NotificationOutboxActor.cs
+++ b/src/ZB.MOM.WW.ScadaBridge.NotificationOutbox/NotificationOutboxActor.cs
@@ -940,7 +940,8 @@ public class NotificationOutboxActor : ReceiveActor, IWithTimers
StuckCutoff: request.StuckOnly ? StuckCutoff(now) : null,
From: request.From,
To: request.To,
- SourceNode: request.SourceNodeFilter);
+ SourceNode: request.SourceNodeFilter,
+ NotificationId: request.NotificationIdFilter);
using var scope = _serviceProvider.CreateScope();
var repository = scope.ServiceProvider.GetRequiredService();
diff --git a/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/Repositories/NotificationOutboxRepositoryIntegrationTests.cs b/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/Repositories/NotificationOutboxRepositoryIntegrationTests.cs
index 93a483eb..8587b73c 100644
--- a/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/Repositories/NotificationOutboxRepositoryIntegrationTests.cs
+++ b/tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/Repositories/NotificationOutboxRepositoryIntegrationTests.cs
@@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Notifications;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
+using ZB.MOM.WW.ScadaBridge.Commons.Types.Notifications;
using ZB.MOM.WW.ScadaBridge.ConfigurationDatabase;
using ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Repositories;
using ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests.Migrations;
@@ -101,6 +102,33 @@ public class NotificationOutboxRepositoryIntegrationTests : IClassFixture(), Arg.Any(), Arg.Any(), Arg.Any())
+ .Returns(((IReadOnlyList)Array.Empty(), 0));
+ var actor = CreateActor();
+
+ actor.Tell(
+ new NotificationOutboxQueryRequest(
+ CorrelationId: "corr-nid",
+ StatusFilter: null,
+ TypeFilter: null,
+ SourceSiteFilter: null,
+ ListNameFilter: null,
+ StuckOnly: false,
+ SubjectKeyword: null,
+ From: null,
+ To: null,
+ PageNumber: 1,
+ PageSize: 50,
+ NotificationIdFilter: "abc"),
+ TestActor);
+
+ var response = ExpectMsg();
+ Assert.True(response.Success);
+
+ // The ?correlationId= deep link from the Flow Debugger / Audit Log rides through
+ // to the repository as an exact-match NotificationId constraint.
+ _repository.Received(1).QueryAsync(
+ Arg.Is(f => f.NotificationId == "abc"),
+ 1, 50, Arg.Any());
+ }
+
[Fact]
public void Query_WithStatusFilterString_ParsesToEnumOnFilter()
{