Description
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) onlistRequests+ REST query params; returntotal- 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_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)
- 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:
listRequestsinpackages/plugins/plugin-approvals/src/approval-service.ts(limit 500, post-filters) - Index caveat:
sys_approval_request.object.tsindexes comment
🤖 Generated with Claude Code
Activity
feat(approvals): approver join table — exact pushdown for approver-fi…