Skip to content

fix(events): add pagination to listEvents to prevent unbounded MongoDB queries#286

Open
anshul23102 wants to merge 1 commit into
omkarhole:mainfrom
anshul23102:fix/issue-281-list-events-pagination
Open

fix(events): add pagination to listEvents to prevent unbounded MongoDB queries#286
anshul23102 wants to merge 1 commit into
omkarhole:mainfrom
anshul23102:fix/issue-281-list-events-pagination

Conversation

@anshul23102
Copy link
Copy Markdown
Contributor

Related Issue

Closes #281

Problem

listEvents called eventCrud.list() with no filter, sort limit, or pagination:

const listEvents = async () => eventCrud.list();

eventCrud.list() maps to model.find({}) with no limit(). As the events collection grows, every call to GET /events fetches the full collection in one round-trip, eventually exhausting available memory and causing response timeouts.

Fix

Three coordinated changes:

1. baseService.js — add optional skip and limit to list

const list = async ({ filter = {}, populate, sort, skip, limit } = {}) => {
  let query = applyQueryOptions(model.find(filter), { populate, sort });
  if (typeof skip  === 'number') query = query.skip(skip);
  if (typeof limit === 'number') query = query.limit(limit);
  return await query;
};

Both parameters are optional (no defaults), so every other caller of eventCrud.list() or any other CRUD service is completely unaffected.

2. eventService.js — paginate listEvents

const listEvents = async ({ page = 1, limit = 20 } = {}) => {
  const safeLimit = Math.min(Math.max(1, Number(limit)), 100);
  const safePage  = Math.max(1, Number(page));
  const skip      = (safePage - 1) * safeLimit;

  const [events, total] = await Promise.all([
    eventCrud.list({ skip, limit: safeLimit }),
    eventCrud.model.countDocuments(),
  ]);

  return { events, total, page: safePage, limit: safeLimit, totalPages: Math.ceil(total / safeLimit) };
};

Promise.all fetches the page and the total count in parallel, keeping the round-trip cost to one extra query.

3. event.controller.js — forward query parameters

const result = await listEventsService({
    page: req.query.page,
    limit: req.query.limit,
});
res.json(result);

Response Shape Change

Before After
Raw array of events { events, total, page, limit, totalPages }

Files Changed

File Change
backend/services/baseService.js Add optional skip and limit to list
backend/services/eventService.js Replace plain eventCrud.list() with paginated implementation
backend/controllers/event.controller.js Forward req.query.page and req.query.limit to service

Testing

  • GET /events returns first 20 events with pagination metadata.
  • GET /events?page=2&limit=10 returns events 11-20.
  • limit=500 is clamped to 100.

Could you please add appropriate labels to this PR? It would help with tracking. Thank you!

…B queries

Fixes omkarhole#281

listEvents called eventCrud.list() with no filter, sort limit, or
pagination, returning every event document from MongoDB in one query.
As the collection grows the response payload grows without bound,
eventually exhausting available memory and causing timeouts.

Changes:
- baseService.list now accepts optional skip and limit options. Both
  default to undefined so all existing callers are unaffected.
- listEvents now accepts page and limit parameters (default page=1,
  default limit=20, max limit=100). It passes the computed skip and
  limit to eventCrud.list and runs a parallel countDocuments call
  using Promise.all so total count is fetched in a single extra
  round-trip, not a sequential one.
- The response shape changes from a raw array to an object with events,
  total, page, limit, and totalPages so clients can build pagination
  controls.
- event.controller.js forwards req.query.page and req.query.limit to
  the service.
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 2, 2026

@anshul23102 is attempting to deploy a commit to the omkarhole's projects Team on Vercel.

A member of the Team first needs to authorize it.

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.

[Bug]: listEvents returns all event records with no pagination or document limit, causing unbounded MongoDB queries

1 participant