feat(site-call-audit): additive TrackedOperationId query filter for ?correlationId= deep links
Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29
This commit is contained in:
+34
@@ -438,6 +438,40 @@ public class SiteCallAuditRepositoryTests : IClassFixture<MsSqlMigrationFixture>
|
||||
Assert.All(rows, r => Assert.Equal(siteA, r.SourceSite));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public async Task QueryAsync_FilterByTrackedOperationId_ReturnsExactlyThatRow()
|
||||
{
|
||||
// Flow Debugger follow-ups Task 2: SiteCallQueryFilter.TrackedOperationId is
|
||||
// an exact PK match (the ?correlationId= deep link). The column is varchar(36)
|
||||
// holding the "D"-format GUID string, so the predicate must compare as a
|
||||
// string — a uniqueidentifier parameter would convert the column side and
|
||||
// defeat the PK seek.
|
||||
Skip.IfNot(_fixture.Available, _fixture.SkipReason);
|
||||
|
||||
var site = NewSiteId();
|
||||
await using var context = CreateContext();
|
||||
var repo = new SiteCallAuditRepository(context);
|
||||
|
||||
var idA = TrackedOperationId.New();
|
||||
var idB = TrackedOperationId.New();
|
||||
var t0 = new DateTime(2026, 9, 6, 10, 0, 0, DateTimeKind.Utc);
|
||||
await repo.UpsertAsync(NewRow(idA, sourceSite: site, createdAtUtc: t0));
|
||||
await repo.UpsertAsync(NewRow(idB, sourceSite: site, createdAtUtc: t0.AddMinutes(1)));
|
||||
|
||||
var rows = await repo.QueryAsync(
|
||||
new SiteCallQueryFilter(TrackedOperationId: idA.Value),
|
||||
new SiteCallPaging(PageSize: 10));
|
||||
|
||||
var row = Assert.Single(rows);
|
||||
Assert.Equal(idA, row.TrackedOperationId);
|
||||
|
||||
// Composes with the other predicates: a mismatching site yields nothing.
|
||||
var none = await repo.QueryAsync(
|
||||
new SiteCallQueryFilter(SourceSite: NewSiteId(), TrackedOperationId: idA.Value),
|
||||
new SiteCallPaging(PageSize: 10));
|
||||
Assert.Empty(none);
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public async Task QueryAsync_KeysetPaging_NoOverlap()
|
||||
{
|
||||
|
||||
@@ -268,6 +268,45 @@ public class SiteCallAuditActorTests : TestKit, IClassFixture<MsSqlMigrationFixt
|
||||
Assert.Equal("Attempted", response.SiteCalls[0].Status);
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public async Task SiteCallQueryRequest_FilterByTrackedOperationId_ReturnsOnlyThatRow()
|
||||
{
|
||||
// Flow Debugger follow-ups Task 2: the ?correlationId= deep link pushes
|
||||
// one operation id into SiteCallQueryRequest.TrackedOperationIdFilter —
|
||||
// the actor must thread it onto SiteCallQueryFilter.TrackedOperationId
|
||||
// so the page returns exactly that row and nothing else from the site.
|
||||
Skip.IfNot(_fixture.Available, _fixture.SkipReason);
|
||||
|
||||
var siteId = NewSiteId();
|
||||
await using var context = CreateContext();
|
||||
var repo = new SiteCallAuditRepository(context);
|
||||
var actor = CreateActor(repo);
|
||||
|
||||
var t0 = new DateTime(2026, 9, 6, 14, 0, 0, DateTimeKind.Utc);
|
||||
var rowA = NewRow(TrackedOperationId.New(), siteId, status: "Attempted", createdAtUtc: t0);
|
||||
var rowB = NewRow(
|
||||
TrackedOperationId.New(), siteId, status: "Delivered",
|
||||
createdAtUtc: t0.AddMinutes(1), terminal: true);
|
||||
await repo.UpsertAsync(rowA);
|
||||
await repo.UpsertAsync(rowB);
|
||||
|
||||
actor.Tell(
|
||||
new SiteCallQueryRequest(
|
||||
"corr-op", StatusFilter: null, SourceSiteFilter: siteId, ChannelFilter: null,
|
||||
TargetKeyword: null, StuckOnly: false, FromUtc: null, ToUtc: null,
|
||||
AfterCreatedAtUtc: null, AfterId: null, PageSize: 50,
|
||||
TrackedOperationIdFilter: rowA.TrackedOperationId.Value),
|
||||
TestActor);
|
||||
|
||||
var response = ExpectMsg<SiteCallQueryResponse>(TimeSpan.FromSeconds(10));
|
||||
Assert.True(response.Success);
|
||||
Assert.Single(response.SiteCalls);
|
||||
Assert.Equal(rowA.TrackedOperationId.Value, response.SiteCalls[0].TrackedOperationId);
|
||||
Assert.Equal("Attempted", response.SiteCalls[0].Status);
|
||||
// No further page — the exact-match filter yields at most one row.
|
||||
Assert.Equal(rowA.TrackedOperationId.Value, response.NextAfterId);
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public async Task SiteCallQueryRequest_KeysetPaging_AdvancesViaCursor()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user