[follow-up] Registry query pagination + tenant enumeration completeness
openContext
Surfaced by C2 (24dcaa6, findings comment 2644d5c). The live harness confirmed registry query responses omit total unless calculateTotal:true is sent, and that Tenant.name has no index (full-text only).
Problem
Two completeness hazards in the current registry layer:
tenant.lookupByNameis O(n): it queries all tenants (empty filter) and matches name in memory, becauseTenant.nameis not filterable. This is fine at spike scale but has no pagination, so a tenant set exceeding the server’s default page size would silently truncate and miss the target — the worst failure mode for an idempotent Ensure (a duplicate tenant could be created).domain.ListForTenantnow detects truncation (total > len(ids)) thanks tocalculateTotal, but it only errors — it does not paginate, so it cannot return a complete listing for tenants with many domains.
Task
- Add pagination to the registry
Querypath (position loop honoring the returnedtotal/page) or expose a pageable query. - Rework
tenant.lookupByNameto be correct under pagination (paginate the full listing, or use a filterable index if one becomes available upstream). - Make
domain.ListForTenantpaginate to completion instead of erroring on truncation. - Add a follow-up decision note if Stalwart gains a name index upstream (then prefer filtering over list+match).
Acceptance
- Unit tests prove a multi-page tenant/domain listing is fully enumerated with no silent truncation.
- Integration test (or a follow-up spike) exercises a listing larger than one page.
Depends on: 24dcaa6 (discovering issue).