fix(site-call-audit): composite keyset cursor eliminates the single-timestamp reconciliation pin; pinned state now a published event

Reconciliation cursor becomes composite (UpdatedAtUtc, TrackedOperationId);
IPullSiteCallsClient/GrpcPullSiteCallsClient forward the Task-15 after_id keyset
(additive param, null preserves the legacy inclusive >= contract). A burst
sharing one exact UpdatedAtUtc now drains via the id tiebreak instead of pinning
forever. A legacy site that ignores after_id is latched + published as
SiteCallReconciliationPinnedChanged on the EventStream (transition-only),
replacing the prior silent log line.
This commit is contained in:
Joseph Doherty
2026-07-09 08:44:07 -04:00
parent 1f4c0b67ca
commit 20098c6108
9 changed files with 324 additions and 66 deletions
@@ -42,7 +42,7 @@ public class SiteCallAuditPurgeTests : TestKit
private sealed class NoOpPullClient : IPullSiteCallsClient
{
public Task<PullSiteCallsResponse> PullAsync(
string siteId, DateTime sinceUtc, int batchSize, CancellationToken ct) =>
string siteId, DateTime sinceUtc, string? afterId, int batchSize, CancellationToken ct) =>
Task.FromResult(new PullSiteCallsResponse(Array.Empty<SiteCall>(), MoreAvailable: false));
}