Skip to content

feat(api): paginate the contact, group, and chat list endpoints - #401

Merged
rmyndharis merged 1 commit into
mainfrom
feat/paginate-list-endpoints
Jun 21, 2026
Merged

feat(api): paginate the contact, group, and chat list endpoints#401
rmyndharis merged 1 commit into
mainfrom
feat/paginate-list-endpoints

Conversation

@rmyndharis

Copy link
Copy Markdown
Owner

Summary

GET /sessions/:id/contacts, /groups, and /chats previously serialized the linked account's entire address book / group / chat set into a single JSON response. For a large account (tens of thousands of contacts) that is a multi-MB heap allocation + GC/event-loop pressure per call, and the rate limiter caps request rate, not response size — so it degrades every session sharing the process.

This adds opt-in pagination:

  • Optional limit (clamped [1, 1000], NaN-safe) and offset query params on all three endpoints.
  • A safe default cap of 1000 when limit is omitted.
  • Chats are sorted most-recent-first before capping, so a bounded response is the newest chats — not an arbitrary slice (this also matches what the dashboard surfaces first).
  • Pagination is applied in the service layer via a shared paginate() helper. The engine still returns the full set to in-process callers — plugins call the engine directly (plugin-loader.service.ts), so they are unaffected.

Compatibility

  • Accounts with ≤ 1000 contacts/groups/chats: no change.
  • Larger accounts: capped by default, page with offset.
  • The dashboard only lists chats (and re-sorts client-side); with the server sorting most-recent-first and capping at 1000, realistic accounts are unchanged. It does not list contacts/groups.

⚠️ Behavior change → warrants a minor release.

Tests (TDD)

  • paginate.spec.ts — default cap, explicit-limit clamp, offset, NaN-safety, under-cap passthrough.
  • contact.service / group.service / session.service specs — cap at 1000, limit/offset applied, chats sorted most-recent-first; the synchronous "session not started" 400 guard is preserved.
  • Full gate: lint 0 · build OK · 1064 unit + 26 e2e pass · dashboard build + lint clean.

Risk

Low/medium. Additive query params with a high default cap; the only behavior delta is the default truncation of >1000-item lists (documented). No engine-interface or adapter change; plugins unaffected.

The contact/group/chat list endpoints serialized the operator's entire address
book / group / chat set into a single response — a heap/GC hazard for very large
accounts. Add optional limit/offset query params (clamped [1,1000]) with a safe
default cap of 1000, applied in the service layer. Chats are sorted most-recent-
first before capping so a bounded response is the newest chats, not an arbitrary
slice.

Pagination is applied at the HTTP/service boundary only: the engine still returns
the full set to in-process callers (plugins use the engine directly), so they are
unaffected. Behavior change (warrants a minor release): a list with >1000 items is
now capped by default; clients page beyond the first window via offset.
@rmyndharis
rmyndharis merged commit c50a3f5 into main Jun 21, 2026
5 checks passed
@rmyndharis
rmyndharis deleted the feat/paginate-list-endpoints branch June 21, 2026 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant