The cross-partition pages (audit log over all tenants, ops events over
all categories) kept one continuation entry per partition that still had
rows. On the tenant fan-out the nextLink outgrew the host's URL limit:
the follow-up request was rejected with HTTP 414 before the function ran,
so Next never loaded a second page for a Global Admin.
The continuation is now the (RowKey, Partition) of the last returned row.
Every page reads each partition through BoundedFanOut (pageSize + 1 rows
after the watermark) and merges by (RowKey, Partition), which is the
display order in both tables. Partitions after the watermark's partition
continue with `RowKey ge`, the others with `RowKey gt`, so equal ops
RowKeys across categories survive a page cut. The merge no longer sorts
by the resolved OccurredUtc while advancing by RowKey, which could skip
rows where the two disagree.
The fan-out was unbounded (Task.WhenAll over every tenant); it now runs
with the shared cross-tenant concurrency ceiling like the session list.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Lands the planned 6-PR pagination rollout (project_mcp_pagination_rollout)
as one tested batch covering session_events, audit+ops, session_reports,
search_sessions/list, and query_raw_events. Backend builds clean; Backend
1024 / Agent V2 1007 / Web 249 tests green.
Primitives (Shared/Pagination):
- ContinuationToken with fingerprint binding (tenantId, dateFrom/To, filters)
so a forged or cross-tenant token fails validation on the next page.
- PaginatedResult<T> + RawPage<TEntity> as the canonical wire shapes.
Backend (AutopilotMonitor.Functions/Pagination):
- AzureTablesPaginator drives single-partition + per-partition pages.
- DateWindowPagination sweeps day-buckets for global audit/ops queries
(the backend resolves "last 30d" once and echoes dateFrom/dateTo on
nextLink so follow-up calls don't recompute "now" and break the token).
- PerPartitionFanOutMerge stable-merges N partition cursors for cross-
tenant session search.
- Per-feature plans (SessionEventsPagination, SearchSessionsPagination,
SearchSessionsByEventPagination, SessionListPagination,
SessionReportsPagination, QueryRawEventsPagination).
- Functions adopt nextLink: GetSessionEvents, GetAuditLogs (tenant +
global), GetOpsEvents, GetSessionReports, SearchSessions,
SearchSessionsByEvent, GetSessions, GetAllSessions, QueryRawEvents.
- Repository contracts (ISessionRepository, IOpsEventRepository,
INotificationRepository, IMaintenanceRepository) gain *PageAsync
variants returning PaginatedResult; legacy GetSessionsAsync becomes
a drain-all helper used by maintenance/feedback/SLA paths that still
need bounded full-list semantics. SessionPage DTO removed.
- PlatformMetricsService now drains all date-bounded sessions via
GetAllSessionsAsync (previous maxResults:500 was a silent truncation).
Web:
- lib/paginationLink.ts + ?? api.ts wrappers expose follow-nextLink in
hooks (useSessionEvents, useDashboardSessions) and pages (audit,
fleet-health, session detail, OpsEvents, SessionReports admin).
- Session list uses Pattern B2 (load-more append); audit + ops + reports
use Pattern B1 (click-next replace); session detail timeline keeps
Pattern A (eager-fetch full set).
MCP:
- followNextLink helper accepts either an opaque continuation OR the
whole "/api/?" path the backend emitted, and follows the latter
verbatim so server-resolved query params (tenantId fingerprint,
resolved dateFrom/dateTo, page size) round-trip correctly. Without
this, get_audit_logs / get_ops_events / list_session_reports / sessions
follow-ups would silently fail token validation.
- get_audit_logs, get_ops_events, list_session_reports, and the session
tools migrate to pageSize + continuation/nextLink, with tool docs
spelling out the round-trip rule so external MCP clients pass the
full nextLink instead of stripping it down to "continuation".
Tests:
- New: ContinuationTokenTests, DateWindowPaginationTests,
PerPartitionFanOutMergeTests, AuditLogRowKeyOrderingTests,
SessionEventsPaginationTests, SessionListPaginationTests,
SearchSessionsPaginationTests, SearchSessionsByEventPaginationTests,
SessionReportsPaginationTests, QueryRawEventsPaginationTests, and
TestSetup helpers.
- Web: paginationLink.test.ts + sessionListLoadMore.test.ts.
- PlatformMetricsServiceWindowTests adjusted for the drain-all change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>