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:
Joseph Doherty
2026-09-06 11:00:03 -04:00
parent 5497ffd181
commit 95773aa9fd
6 changed files with 98 additions and 3 deletions
@@ -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()
{