Skip to content

fix(backend): add cursor pagination to enrollment and queue list endpoints - #231

Open
jajafwangshak86-ops wants to merge 1 commit into
Stellar-Deejah:mainfrom
jajafwangshak86-ops:fix/182-pagination-unbounded-list-endpoints
Open

fix(backend): add cursor pagination to enrollment and queue list endpoints#231
jajafwangshak86-ops wants to merge 1 commit into
Stellar-Deejah:mainfrom
jajafwangshak86-ops:fix/182-pagination-unbounded-list-endpoints

Conversation

@jajafwangshak86-ops

Copy link
Copy Markdown

Summary

Closes #182

Adds cursor-based pagination to the three unbounded list endpoints identified in the issue, preventing multi-MB responses on busy deployments.

Changes

New file: backend/src/utils/pagination.ts

  • paginate<T>(items, opts) helper that slices an array by limit + cursor offset
  • Uses the SDK's canonical encodeCursor/decodeCursor (format: base64("0:index")) so cursor semantics are shared across the stack
  • Default limit 50, hard cap 200, invalid cursor throws ValidationError (→ 400)

backend/src/routes/enrollments.ts

  • GET /api/enrollments/:identity — accepts ?limit and ?cursor, returns { items, nextCursor, total }
  • GET /api/enrollments/queue/:queueId — same pagination contract

backend/src/routes/queues.ts

  • GET /api/queues — accepts ?limit, ?cursor, and existing ?status filter; returns { items, nextCursor, total }

Before / After response shapes

Before (unbounded):

GET /api/enrollments/queue/sneaker-drop-001
→ [ { ... }, { ... }, ...50000 records ]

After (paginated):

GET /api/enrollments/queue/sneaker-drop-001?limit=50
→ {
    "items": [ ...50 records ],
    "nextCursor": "MDox",
    "total": 50000
  }
GET /api/enrollments/queue/sneaker-drop-001?limit=50&cursor=MDox
→ { "items": [ ...next 50 ], "nextCursor": "MDoy", "total": 50000 }

Backward compatibility

Omitting limit and cursor returns the first 50 items in the paginated envelope — callers that previously iterated a bare array will need to read .items, but no params → no breakage at the transport level.

Tests

  • Fixed stale assertions in enrollments.route.test.ts that expected bare arrays
  • Fixed queues.route.test.ts cursor values to use the correct encodeCursor(0, N) format and error shape (res.body.error.message)
  • Added multi-page traversal tests for both enrollment endpoints (3 records, limit 2 → page 1 returns 2 items + cursor, page 2 returns 1 item + null cursor)
  • All 156 backend tests pass

Docs

  • docs/api-reference/enrollments.md — updated response schema with pagination envelope and query param table
  • docs/api-reference/queues.md — updated to show paginated envelope and full query param table

…oints (Stellar-Deejah#182)

- Add backend/src/utils/pagination.ts with paginate() helper using SDK's
  encodeCursor/decodeCursor for the canonical 0:index cursor format
- Update GET /api/enrollments/:identity to accept limit/cursor params and
  return { items, nextCursor, total } envelope (default limit 50, max 200)
- Update GET /api/enrollments/queue/:queueId with same pagination contract
- Update GET /api/queues with limit/cursor/status query support
- Fix stale test assertions in enrollments.route.test.ts and queues.route.test.ts
  to expect paginated envelope and correct encodeCursor(0,N) cursor values
- Add multi-page traversal tests for both enrollment list endpoints
- Update docs/api-reference/enrollments.md and queues.md with pagination schema

Closes Stellar-Deejah#182
@vercel

vercel Bot commented Aug 27, 2026

Copy link
Copy Markdown

@jajafwangshak86-ops is attempting to deploy a commit to the Deejah 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.

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

1 participant