Category Labels: backend, pagination, api, performance, refactor
Summary: Standardize cursor-based pagination across every list endpoint in the backend with consistent request/response shapes, documented in docs/api.md.
Background: The backend has backend/src/middleware/pagination.js and backend/src/utils/paginate.js which provide cursor-based pagination. However, not all list endpoints use them consistently. The accounts.js, payments.js, tips.js, events.js, analytics.js, webhooks.js, and turrets.js routes each implement pagination slightly differently. Tests in backend/__tests__/pagination.test.js cover some but not all endpoints.
Problem Statement: Inconsistent pagination across endpoints creates a confusing developer experience. Some endpoints use ?cursor= + ?limit=, others use ?page= + ?size=, and error responses vary.
Objectives:
- Standardize on cursor-based pagination with parameters:
cursor (opaque string), limit (default 20, max 100).
- Standardize response shape:
{ data: [...], pagination: { nextCursor, hasMore, total } }.
- Apply to all list endpoints: accounts, payments, tips, events, analytics, webhooks, turrets, scheduled transactions.
- Update
docs/api.md with the standardized pagination spec.
- Add pagination tests for all endpoints.
Scope:
- In scope: cursor pagination standardization, response shape, docs, tests.
- Out of scope: offset-based pagination, keyset pagination for different use cases.
Detailed Implementation Requirements:
- Create
backend/src/middleware/pagination.js (unify existing implementations):
function paginationMiddleware(req, res, next) {
const cursor = req.query.cursor || null;
const limit = Math.min(parseInt(req.query.limit) || 20, 100);
req.pagination = { cursor, limit };
next();
}
module.exports = paginationMiddleware;
- Create
backend/src/utils/paginate.js response formatter:
function formatPaginatedResponse(data, cursor, total) {
const hasMore = data.length > 0; // or check against total
return {
data,
pagination: {
nextCursor: data.length > 0 ? cursor : null,
hasMore,
total: total || null,
}
};
}
- Apply
paginationMiddleware to all list routes in backend/src/server.js.
- Update each route handler:
accounts.js: GET /api/v1/accounts/:pk/payments → standardized pagination.
payments.js: GET /api/v1/payments/:pk → standardized.
tips.js: GET /api/v1/tips/:pk → standardized.
events.js: GET /api/v1/events/:pk → standardized.
webhooks.js: GET /api/v1/webhooks/:pk → standardized.
turrets.js: GET /api/v1/turrets/:pk → standardized.
scheduledTransactions.js: GET /api/v1/scheduled/:pk → standardized.
- Update
docs/api.md with a dedicated "Pagination" section.
- Add/update tests in
backend/__tests__/pagination.test.js.
Expected Architecture:
backend/src/
├── middleware/
│ └── pagination.js (unified)
├── utils/
│ └── paginate.js (response formatter)
├── routes/ (updated: standardized pagination)
└── server.js (apply middleware globally)
docs/api.md (pagination section)
Acceptance Criteria:
- All list endpoints accept
?cursor=&limit= parameters.
- All list endpoints return
{ data, pagination: { nextCursor, hasMore, total } }.
limit defaults to 20, max 100.
- Documentation in
docs/api.md is accurate.
- All existing and new pagination tests pass.
- CI: Backend tests pass in
.github/workflows/ci.yml → backend job.
CI Validation: This issue includes acceptance criteria that must pass CI checks in .github/workflows/ci.yml. PRs solving this issue must pass all relevant CI jobs before merging.
Summary: Standardize cursor-based pagination across every list endpoint in the backend with consistent request/response shapes, documented in
docs/api.md.Background: The backend has
backend/src/middleware/pagination.jsandbackend/src/utils/paginate.jswhich provide cursor-based pagination. However, not all list endpoints use them consistently. Theaccounts.js,payments.js,tips.js,events.js,analytics.js,webhooks.js, andturrets.jsroutes each implement pagination slightly differently. Tests inbackend/__tests__/pagination.test.jscover some but not all endpoints.Problem Statement: Inconsistent pagination across endpoints creates a confusing developer experience. Some endpoints use
?cursor=+?limit=, others use?page=+?size=, and error responses vary.Objectives:
cursor(opaque string),limit(default 20, max 100).{ data: [...], pagination: { nextCursor, hasMore, total } }.docs/api.mdwith the standardized pagination spec.Scope:
Detailed Implementation Requirements:
backend/src/middleware/pagination.js(unify existing implementations):backend/src/utils/paginate.jsresponse formatter:paginationMiddlewareto all list routes inbackend/src/server.js.accounts.js:GET /api/v1/accounts/:pk/payments→ standardized pagination.payments.js:GET /api/v1/payments/:pk→ standardized.tips.js:GET /api/v1/tips/:pk→ standardized.events.js:GET /api/v1/events/:pk→ standardized.webhooks.js:GET /api/v1/webhooks/:pk→ standardized.turrets.js:GET /api/v1/turrets/:pk→ standardized.scheduledTransactions.js:GET /api/v1/scheduled/:pk→ standardized.docs/api.mdwith a dedicated "Pagination" section.backend/__tests__/pagination.test.js.Expected Architecture:
Acceptance Criteria:
?cursor=&limit=parameters.{ data, pagination: { nextCursor, hasMore, total } }.limitdefaults to 20, max 100.docs/api.mdis accurate..github/workflows/ci.yml→backendjob.CI Validation: This issue includes acceptance criteria that must pass CI checks in
.github/workflows/ci.yml. PRs solving this issue must pass all relevant CI jobs before merging.