fix: implement pagination/filtering/sorting standards (#257) and background job processing (#258) - #368
Merged
Penielka merged 1 commit intoJul 30, 2026
Conversation
… 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
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 registrybackend/src/middleware/schemas/paginationSchemas.ts— Joi validation forlimit,cursor,sort,order, and filter paramsbackend/src/middleware/pagination.ts— Express middleware that validates & attachesreq.pagination+req.listFiltersModified Files
backend/src/controllers/EnrollmentController.ts—getUserEnrollmentsandgetCourseEnrollmentsnow use cursor-based pagination withnext_cursor/total_count/has_moreresponse metadatabackend/src/docs/openapi.ts— AddedCursorPaginationschemaStandard Query Parameters
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/removeJobbackend/src/controllers/jobController.ts— 8 endpoints: stats, list/filter jobs, job detail, job progress, retry dead-letter, remove job, enqueue job, list dead-letterbackend/src/routes/jobRoutes.ts— REST routes at/api/jobsModified Files
backend/src/index.ts— Job queue initialized at startup with 8 built-in handler types, routes mounted at/api/jobsand/api/v1/jobs, graceful shutdown integrationbackend/src/docs/openapi.ts— AddedJob,JobStats,EnqueueJobRequestschemas +JobstagSupported Job Types
email,credential_minting,analytics_aggregation,notification,report_generation,data_export,content_processing,generalAPI Endpoints
TypeScript
Typecheck passes with 0 new errors. The only pre-existing error is an unrelated
graphqlBootstrapreference on line 549 of index.ts.Files Changed