Skip to content

feat: Add enrollments v2 list endpoint#38155

Draft
brianjbuck-wgu wants to merge 2 commits intoopenedx:masterfrom
WGU-Open-edX:feature/37536-enrollments-api-lists
Draft

feat: Add enrollments v2 list endpoint#38155
brianjbuck-wgu wants to merge 2 commits intoopenedx:masterfrom
WGU-Open-edX:feature/37536-enrollments-api-lists

Conversation

@brianjbuck-wgu
Copy link
Contributor

Description

Adds two capabilities needed by the new Enrollments screen in the instructor dashboard MFE:

  1. New list_course_enrollments endpoint — A new POST /courses/{course_id}/instructor/api/list_course_enrollments endpoint that returns a paginated, searchable list of all active course enrollments. Returns user data (username, email, first_name, last_name) with total count and pagination metadata.

  2. Search and pagination for list_course_role_members — Enhances the existing POST /courses/{course_id}/instructor/api/list_course_role_members endpoint with optional search, page, and page_size parameters while maintaining full backward compatibility.

Changes:

  • api.py: Added ListCourseEnrollmentsView with VIEW_ENROLLMENTS permission (HasAccessRule('staff')). Enhanced ListCourseRoleMembersView with search filtering and pagination support.
  • api_urls.py: Registered the new list_course_enrollments URL pattern.
  • serializer.py: Added EnrollmentListSerializer for request validation. Extended RoleNameSerializer with optional search, page, and page_size fields.

Shared features across both endpoints:

  • Search filters by username, email, first_name, or last_name (case-insensitive)
  • Pagination with configurable page_size (default: 20, max: 100)
  • Response includes count, num_pages, and current_page metadata

User roles impacted: Course Staff, Course Instructors, Developers building against the instructor API.

Supporting information

Testing instructions

List Course Enrollments

  1. As a course staff/instructor user, POST /courses/{course_id}/instructor/api/list_course_enrollments with an empty body {}.
  2. Verify the response includes course_id, enrollments (list of user objects), count, num_pages, and current_page.
  3. Verify only active enrollments are included (inactive enrollments should be excluded).
  4. Test search: send {"search": "partial_username"} and verify filtered results.
  5. Test pagination: send {"page": 1, "page_size": 5} and verify correct page size and metadata.
  6. Test invalid inputs: {"page": 0} and {"page_size": 0} should return 400.
  7. Test permission: a non-staff user should receive 403.

List Course Role Members (search/pagination)

  1. As a course instructor, POST /courses/{course_id}/instructor/api/list_course_role_members with {"rolename": "beta"}.
  2. Verify the response now includes count, num_pages, and current_page fields.
  3. Verify backward compatibility: omitting search, page, and page_size returns paginated results with defaults (page 1, page_size 20).
  4. Test search: send {"rolename": "beta", "search": "username"} and verify filtered results.
  5. Test pagination: send {"rolename": "beta", "page": 2, "page_size": 10} and verify correct paging.

Deadline

None

Other information

  • No database migrations required.
  • The ListCourseEnrollmentsView uses the VIEW_ENROLLMENTS permission (HasAccessRule('staff')) to allow course staff and instructors access, consistent with other enrollment-viewing endpoints.
  • The list_course_role_members changes are fully backward compatible — existing callers without the new parameters will receive the same data, now paginated with defaults.
  • The enrollment list endpoint uses database-level filtering (Django ORM Q objects) for search, while the role members endpoint uses in-memory filtering since list_with_level returns a Python list.

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Mar 11, 2026
@openedx-webhooks
Copy link

Thanks for the pull request, @brianjbuck-wgu!

This repository is currently maintained by @openedx/wg-maintenance-openedx-platform.

Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review.

🔘 Get product approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.
🔘 Provide context

To help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads
🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.

🔘 Update the status of your PR

Your PR is currently marked as a draft. After completing the steps above, update its status by clicking "Ready for Review", or removing "WIP" from the title, as appropriate.


Where can I find more information?

If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:

When can I expect my changes to be merged?

Our goal is to get community contributions seen and reviewed as efficiently as possible.

However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

@mphilbrick211 mphilbrick211 added the mao-onboarding Reviewing this will help onboard devs from an Axim mission-aligned organization (MAO). label Mar 11, 2026
@mphilbrick211 mphilbrick211 moved this from Needs Triage to Waiting on Author in Contributions Mar 11, 2026
@brianjbuck-wgu brianjbuck-wgu requested a review from Copilot March 12, 2026 15:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new list_course_enrollments endpoint and enhances the existing list_course_role_members endpoint with search and pagination support for the instructor dashboard MFE.

Changes:

  • New ListCourseEnrollmentsView with DB-level search filtering and pagination for active course enrollments
  • Enhanced ListCourseRoleMembersView with optional search, page, and page_size parameters (backward compatible)
  • New serializers and comprehensive test coverage for both endpoints

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
lms/djangoapps/instructor/views/api.py New ListCourseEnrollmentsView and search/pagination for ListCourseRoleMembersView
lms/djangoapps/instructor/views/api_urls.py Registers the new list_course_enrollments URL
lms/djangoapps/instructor/views/serializer.py New EnrollmentListSerializer and extended RoleNameSerializer with search/pagination fields
lms/djangoapps/instructor/tests/test_enrollment_list_api.py Comprehensive tests for both endpoints
lms/djangoapps/instructor/tests/test_api.py Updates existing tests to include new pagination metadata fields

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

"""
course_key = CourseKey.from_string(course_id)
course = get_course_with_access(
request.user, 'instructor', course_key, depth=None
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: get_course_with_access is called with 'instructor' access level, but permission_name is set to permissions.VIEW_ENROLLMENTS which corresponds to HasAccessRule('staff'). This means course staff users will pass the permission check but then get a 404 from get_course_with_access since they don't have instructor-level access. This should use 'staff' instead of 'instructor' to be consistent with the permission, or match what the ListCourseRoleMembersView does (which uses EDIT_COURSE_ACCESS permission with 'instructor' access level).

Suggested change
request.user, 'instructor', course_key, depth=None
request.user, 'staff', course_key, depth=None

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mao-onboarding Reviewing this will help onboard devs from an Axim mission-aligned organization (MAO). open-source-contribution PR author is not from Axim or 2U

Projects

Status: Waiting on Author

Development

Successfully merging this pull request may close these issues.

4 participants