You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BE] GET Competency Statuses for Learner in Course #738
As a learner, I need to know what mastery level I demonstrated on each subsection as well as my overall mastery level for each competency assessed in the course in order to understand what I need to work on improving and how I can speak about my skills.
Description
This ticket is for building a GET endpoint that fetches the Competency Status for all competency criteria and parent competencies in a given course for a given learner.
This endpoint should do the following logic. Steps 1, 3, and 4 skip anything #733 excludes (archived criteria, groups, tags, and taxonomies, and disabled taxonomies), so the response covers exactly the items #733 returns.
Get the course-level CompetencyCriteriaGroups for this course: the groups whose course_id points to the CourseRun for this course run key. There is one per competency assessed in the course.
Get the StudentCompetencyStatus records where user_id is the learner's id and oel_tagging_tag_id is the tag of one of those course-level groups or one of that tag's ancestor tags. Include all of these records in the response payload.
Get all the CompetencyCriteriaGroups whose parent_id is one of the course-level groups fetched in step 1.
Get all CompetencyCriterion records that belong to the groups fetched in steps 1 and 3.
Get all StudentCompetencyCriteriaStatus records where user_id is the learner's id and competency_criteria_id is one of the CompetencyCriterion ids fetched in step 4. Include all of these records in the response payload.
Join each status record to CompetencyMasteryStatus so the response payload carries the status value (for example, "Demonstrated") rather than its id.
The response payload will then resemble something to the effect of the following:
Whose statuses: full parity with today's Progress tab. The learner sees their own statuses, course staff (and CCX coaches) see a specific learner's statuses on the "view this learner's progress" page, and staff masquerading as a specific learner see that learner's statuses.
Where the effective-learner decision lives: the openedx-core view takes an optional learner id and asks a resolver named in the OPENEDX_LEARNING settings who the learner is. The default resolver allows only the requester. The LMS points the setting at a function extracted from ProgressTabView._get_student_user, which both views then share. Give the resolver a generic name so [EPIC-SP] Competency Status Summary Sidebar #742, [EPIC-SP] Competency Status Sunburst #745, and [EPIC-SP] Recommended Next Action #753 can reuse it.
Archived and disabled items: return statuses for exactly the set of items [BE] GET Competency Criteria for Course #733 returns. Statuses for archived criteria, groups, tags, or taxonomies, and for disabled taxonomies, are left out.
Competency-level status: return only the learner's overall, cross-course StudentCompetencyStatus. Course-run group statuses are out of scope and can be added later without breaking callers.
CCX courses are out of scope for MVP.
An item with no status row is left out of the response, and the frontend shows it as "Available". A malformed course key returns 400, and an unknown well-formed key returns an empty response, as in [BE] GET Competency Criteria for Course #733. A requester who isn't allowed to see another learner gets 404, matching ProgressTabView.
Stored statuses are returned as they are, with no recomputation at read time. The brief lag from asynchronous roll-up (ADR 0004) is accepted.
The per-subsection percentage score is out of scope for [BE] GET Competency Statuses for Learner in Course #738. When the plugin needs it, the plugin calls the existing Progress tab API (/api/course_home/v1/progress/{course_key}) itself, which returns block_key and percent_graded for each subsection.
Group course scope follows [BE] Create CompetencyCriteria #665's implementation in PR Alezconsultant/665 criterion endpoint on 846 #847: only the course-level group's course_id points to the course run, and bottom-tier groups have a null course_id and are found through their parent. ADR 0002's amended Decision 2 says every group in a course subtree carries course_id, which conflicts with this.
Each status is returned as the lookup row's status string, never its id.
The response carries no learner identifier, so it can't undercut the Progress tab's option to hide a learner's username.
Staff masquerading as a role or content group, rather than a specific learner, get their own statuses, the same as the Progress tab shows their own grades.
If a masqueraded learner has since unenrolled, the masquerade is cleared and the endpoint returns the staff member's own statuses, the same as ProgressTabView.
Drafting in Progress
User Story
As a learner, I need to know what mastery level I demonstrated on each subsection as well as my overall mastery level for each competency assessed in the course in order to understand what I need to work on improving and how I can speak about my skills.
Description
This ticket is for building a GET endpoint that fetches the Competency Status for all competency criteria and parent competencies in a given course for a given learner.
This endpoint should do the following logic. Steps 1, 3, and 4 skip anything #733 excludes (archived criteria, groups, tags, and taxonomies, and disabled taxonomies), so the response covers exactly the items #733 returns.
The response payload will then resemble something to the effect of the following:
{ "student_competency_statuses": [{"tag_id": 40, "status": "PartiallyAttempted"}, {"tag_id": 41, "status": "PartiallyAttempted"}], "student_competency_criteria_statuses": [{"criterion_id": 90, "status": "Demonstrated"}, {"criterion_id": 91, "status": "AttemptedNotDemonstrated"}] }Context
Notes for drafting
Decisions from the pre-handoff check
OPENEDX_LEARNINGsettings who the learner is. The default resolver allows only the requester. The LMS points the setting at a function extracted fromProgressTabView._get_student_user, which both views then share. Give the resolver a generic name so [EPIC-SP] Competency Status Summary Sidebar #742, [EPIC-SP] Competency Status Sunburst #745, and [EPIC-SP] Recommended Next Action #753 can reuse it.StudentCompetencyStatus. Course-run group statuses are out of scope and can be added later without breaking callers.ProgressTabView./api/course_home/v1/progress/{course_key}) itself, which returnsblock_keyandpercent_gradedfor each subsection.course_idpoints to the course run, and bottom-tier groups have a nullcourse_idand are found through their parent. ADR 0002's amended Decision 2 says every group in a course subtree carriescourse_id, which conflicts with this.ProgressTabView.