Skip to content

fix: implement pagination/filtering/sorting standards (#257) and background job processing (#258) - #368

Merged
Penielka merged 1 commit into
AetherEdu:mainfrom
boss572:fix/issues-257-258-pagination-and-job-queue
Jul 30, 2026
Merged

fix: implement pagination/filtering/sorting standards (#257) and background job processing (#258)#368
Penielka merged 1 commit into
AetherEdu:mainfrom
boss572:fix/issues-257-258-pagination-and-job-queue

Conversation

@boss572

@boss572 boss572 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #257, Closes #258

This PR implements two backend enhancements: cursor-based pagination standards for all list endpoints, and a general-purpose background job processing system with retry and dead-letter queues.

Issue #257 — Cursor-Based Pagination, Filtering & Sorting

New Files

  • backend/src/utils/pagination.ts — Core types (PaginationParams, PaginationMeta, ListFilters), helpers (encodeCursor, decodeCursor, buildPaginationMeta, parsePaginationParams, parseFilters), and sort-field allowlist registry
  • backend/src/middleware/schemas/paginationSchemas.ts — Joi validation for limit, cursor, sort, order, and filter params
  • backend/src/middleware/pagination.ts — Express middleware that validates & attaches req.pagination + req.listFilters

Modified Files

  • backend/src/controllers/EnrollmentController.tsgetUserEnrollments and getCourseEnrollments now use cursor-based pagination with next_cursor/total_count/has_more response metadata
  • backend/src/docs/openapi.ts — Added CursorPagination schema

Standard Query Parameters

?limit=20&cursor=...&sort=enrolledAt&order=desc&status=active&type=course

Standard Response Metadata

{
  "pagination": {
    "next_cursor": "base64url-encoded-value",
    "total_count": 250,
    "has_more": true
  }
}

Issue #258 — Background Job Processing

New Files

  • backend/src/services/jobQueue.ts — Redis-backed job queue with persistent storage, typed Redis client, retry with exponential backoff (1s → 5min cap), dead-letter queue, enqueue/getJob/getStats/listJobs/retryDeadLetter/removeJob
  • backend/src/controllers/jobController.ts — 8 endpoints: stats, list/filter jobs, job detail, job progress, retry dead-letter, remove job, enqueue job, list dead-letter
  • backend/src/routes/jobRoutes.ts — REST routes at /api/jobs

Modified Files

  • backend/src/index.ts — Job queue initialized at startup with 8 built-in handler types, routes mounted at /api/jobs and /api/v1/jobs, graceful shutdown integration
  • backend/src/docs/openapi.ts — Added Job, JobStats, EnqueueJobRequest schemas + Jobs tag

Supported Job Types

email, credential_minting, analytics_aggregation, notification, report_generation, data_export, content_processing, general

API Endpoints

Method Path Description
GET /api/jobs/stats Aggregate job statistics
GET /api/jobs List jobs (filterable, paginated)
POST /api/jobs Enqueue a new job
GET /api/jobs/:id Get job details
GET /api/jobs/:id/progress Get job progress
POST /api/jobs/:id/retry Retry dead-lettered job
DELETE /api/jobs/:id Remove a job
GET /api/jobs/dead-letter List dead-lettered jobs

TypeScript

Typecheck passes with 0 new errors. The only pre-existing error is an unrelated graphqlBootstrap reference on line 549 of index.ts.

Files Changed

9 files changed, 1321 insertions(+), 47 deletions(-)
backend/src/controllers/EnrollmentController.ts   (modified)
backend/src/controllers/jobController.ts           (new)
backend/src/docs/openapi.ts                         (modified)
backend/src/index.ts                                (modified)
backend/src/middleware/pagination.ts                (new)
backend/src/middleware/schemas/paginationSchemas.ts (new)
backend/src/routes/jobRoutes.ts                     (new)
backend/src/services/jobQueue.ts                    (new)
backend/src/utils/pagination.ts                     (new)

… and background job processing (AetherEdu#258)

Closes AetherEdu#257, Closes AetherEdu#258

Issue AetherEdu#257 - Cursor-based pagination, filtering, and sorting:
- Add shared pagination utility with cursor encode/decode, metadata builders,
  filter parsers, and sort-field allowlist registry
- Add Joi validation schemas for standard query params (limit, cursor, sort,
  order, filter)
- Add Express pagination middleware that validates and attaches typed
  pagination + filter data to requests
- Migrate EnrollmentController list endpoints (getUserEnrollments,
  getCourseEnrollments) from offset-based to cursor-based pagination with
  next_cursor/total_count/has_more response metadata
- Add CursorPagination schema to OpenAPI docs

Issue AetherEdu#258 - Background job processing with retry and dead-letter queues:
- Add Redis-backed general-purpose job queue with persistent storage,
  exponential backoff (1s-5min cap), and dead-letter queue
- Add job controller with endpoints for stats, listing/filtering, detail,
  progress tracking, dead-letter retry, removal, and enqueue
- Add job routes mounted at /api/jobs and /api/v1/jobs
- Register 8 built-in handler types (email, credential_minting,
  analytics_aggregation, notification, report_generation, data_export,
  content_processing, general)
- Integrate job queue startup and graceful shutdown in index.ts
- Add Job, JobStats, EnqueueJobRequest schemas to OpenAPI docs
@Penielka
Penielka merged commit 9fb3bf9 into AetherEdu:main Jul 30, 2026
10 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants