Skip to content

Backend: GET /api/enrollments endpoints return unbounded lists — no pagination on identity or queue lookups #182

Description

@k-deejah

Difficulty: Advanced

Problem

1. GET /api/enrollments/:identity returns all records for an identity with no limit
backend/src/routes/enrollments.ts lines 47–51 calls getEnrollmentsByIdentity(identity) which returns the full enrollmentStore.get(identity) array. An identity enrolled in thousands of queues generates a payload with thousands of records in a single HTTP response. No limit, offset, or cursor parameter exists.

2. GET /api/enrollments/queue/:queueId also returns unbounded lists
backend/src/routes/enrollments.ts lines 43–46 calls getEnrollmentsByQueue(queueId) with no pagination. A queue with 50,000 participants returns all 50,000 records in a single response. This would be a multi-MB JSON response that crashes browser tabs and timeouts mobile connections.

3. No pagination on GET /api/queues either — returns entire mockQueues array
backend/src/routes/queues.ts lines 24–30: the list endpoint returns mockQueues directly with only a status filter. With hundreds of queues, this is also unbounded. Issue #21 covers the frontend virtualization side but the backend API itself has no limit/cursor support at the route level.

Impact: Any moderately busy deployment will produce multi-MB API responses. Browsers will run out of memory parsing them. The backend process will spike CPU serializing massive JSON payloads. Rate limiting (issue #108) is insufficient if a single request can return megabytes.

Proposed Solution

  • Add limit (default 50, max 200) and cursor query params to all three list endpoints.
  • Return { items: [...], nextCursor: string | null, total: number } envelope.
  • Use sdk/src/pagination.ts cursor helpers (encodeCursor/decodeCursor) as the canonical format.
  • Update frontend useQueues, useEnrollment hooks to consume the paginated envelope.

Acceptance Criteria

  • GET /api/enrollments/:identity accepts limit and cursor query params
  • GET /api/enrollments/queue/:queueId accepts limit and cursor query params
  • GET /api/queues accepts limit and cursor query params
  • All three return { items, nextCursor, total } envelope
  • Default limit 50, max limit 200, invalid limit returns 400
  • Cursor encoding uses sdk/src/pagination.ts helpers
  • Frontend hooks updated to handle paginated response shape
  • Route tests cover paginated and unpaginated (backward-compat no-params) requests
  • docs/api-reference/ updated with pagination schema

Contributor Note

If assigned, your PR must show the before/after response shapes, include a test demonstrating multi-page traversal, and confirm backward compatibility (no params → returns first 50 items).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions