Context
ApprovalService.listRequests hard-caps at limit: 500 and returns everything in one shot; the Console inbox (objectstack-ai/objectui, ApprovalsInboxPage) sorts/filters/searches client-side. The request table is append-only (every flow trigger adds a row), so a real tenant crosses 500 within weeks — at which point the "All" tab slows down and rows beyond 500 silently disappear (the dangerous half).
Scope
Server (this repo)
limit/offset (or cursor) on listRequests + REST query params; return total
- Push the filters the client currently applies in memory down into engine queries: status, object, free-text (record title / requester / process label)
- The known obstacle:
pending_approvers is a CSV string and "my pending" matching is a post-filter in memory (acknowledged in the code comments). Pagination makes that incorrect — either push it down as a LIKE-composite, or (recommended) split approvers into a join table. The migration also fixes the long-standing indexing note on sys_approval_request ("the engine does a post-filter substring match per row").
Console (objectstack-ai/objectui)
- Load-more / pager on the inbox tables; debounced server-side search
- Keep the enriched display contract (
record_title, payload_display, …) — enrichment is already batched per page server-side, so cost scales with page size
Trigger
Do this before any real tenant's request table reaches a few hundred rows, or as soon as the "All" tab is perceptibly slow. Recommend bundling the approver join-table migration into the same change — one migration solves both matching performance and pagination correctness.
References
- Current implementation:
listRequests in packages/plugins/plugin-approvals/src/approval-service.ts (limit 500, post-filters)
- Index caveat:
sys_approval_request.object.ts indexes comment
🤖 Generated with Claude Code
Context
ApprovalService.listRequestshard-caps atlimit: 500and returns everything in one shot; the Console inbox (objectstack-ai/objectui,ApprovalsInboxPage) sorts/filters/searches client-side. The request table is append-only (every flow trigger adds a row), so a real tenant crosses 500 within weeks — at which point the "All" tab slows down and rows beyond 500 silently disappear (the dangerous half).Scope
Server (this repo)
limit/offset(or cursor) onlistRequests+ REST query params; returntotalpending_approversis a CSV string and "my pending" matching is a post-filter in memory (acknowledged in the code comments). Pagination makes that incorrect — either push it down as a LIKE-composite, or (recommended) split approvers into a join table. The migration also fixes the long-standing indexing note onsys_approval_request("the engine does a post-filter substring match per row").Console (objectstack-ai/objectui)
record_title,payload_display, …) — enrichment is already batched per page server-side, so cost scales with page sizeTrigger
Do this before any real tenant's request table reaches a few hundred rows, or as soon as the "All" tab is perceptibly slow. Recommend bundling the approver join-table migration into the same change — one migration solves both matching performance and pagination correctness.
References
listRequestsinpackages/plugins/plugin-approvals/src/approval-service.ts(limit 500, post-filters)sys_approval_request.object.tsindexes comment🤖 Generated with Claude Code