Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. Decouple backend ids from BadgeClass slugs in Open edX
  2. Supports these use cases for creating and awarding badges:
    1. (new) Admin creates a BadgeClass in Django admin, matching existing BadgeClass in Badgr.  Same Badge image is uploaded to Badgr and LMS admin.  Course id specified. Mode optional.  When learner earns certificate in specified course and mode, learner will automatically be awarded a badge for this BadgeClass.  If mode not specified, when learner earns certificate in specified course, and no other BadgeClass exists specifying both the course and mode matching the learner, the learner will automatically be awarded a badge for this BadgeClass.
    2. (new) Admin creates a BadgeClass in Django admin, matching existing Badge Class in Badgr.  Same Badge image is uploaded to Badgr and LMS admin.  Course id not specified.  Mode is not specified.  BadgeClass can be used for course group, enrollment, or completion number badges.  
    3. (bugfix) Admin creates a BadgeClass in Django admin.  No existing backend Badge Class exists.  When first learner earns a certificate in this course, Badge Class created in Badgr with matching name, criteria, description and image.  New backend id retrieved and stored on BadgeClass object in Open edX.   Learner awarded badge in new Badge Class.  
    4. (bugfix) Admin enables badges on a course but does not create a BadgeClass in Django admin.  When first learner earns a certificate in this course, BadgeClass created in Django with course id, course mode matching learner's certificate, and default course mode badge image.  Description and criteria auto-generated as current functionality from course name/dates and about page URL respectively.  Matching Badge Class created in Badgr backend.  Backend id stored on Django BadgeClass.  Learner is awarded a badge in Badgr.  
    5. (bugfix) Admin creates an entry in  enrollment, course group, or course completion number badge event configurations using Open edX BadgeClass slug as the key.  Learner enrolls in or completes x number of courses, or earns a certificate in all courses in course group.  Badge awarded in backend for Badgr Badge Class with backend id paired with Open edX slug in configuration entry. 

...

* [ X] Documentation review  - documentation of changes to Badging will be outside of the PR



Steps to Test or Reproduce Current Problems

The following steps will demonstrate the current problem with generating and awarding badges via Badgr.io.  Some of the expected results may not have been original intentions of the badges app creator, but are likely expectations of users.

...

Development and Design Notes


(new) Course completion badges awarding turned off by default

In our experience (at Appsembler), end users do not wish to award badges for completion of all courses.  Other changes proposed here would make BadgeClass creation and badge issuance automatic for all courses with "Issue Open Badges" set to True.  This should be changed to default to False to support the more likely common use case.  Site-wide feature flag ENABLE_OPENBADGES should continue to default to False.  


(bugfix) Changes to BadgeClass slugs

Currently, BadgeClass slugs are not unique.  Uniqueness of BadgeClasses is determined by a combination of slug, course id, and issuing component.  I propose making slug unique, and using AutoSlugField to generate a sensible value from the combination of course id, mode, and issuing component if used (This would involve adding AutoSlugField as a new requirement).  BadgeClasses would be unique by slug, as well as by course id and mode together.  


(bugfix) Separate Open edX BadgeClass slug from backend Badge Class id 

The main issue is that Badgr.io will no longer accept a custom slug when creating a Badge Class through the API.  It now populates the 'slug' AutoSlugField and related Id field with a UUID-based identifier.  The LMS badges app currently "slugifies" the BadgeClass Name and Issuing Component values and passes that to the Badgr API as the requested backend Badge Class slug, expecting that this will be a way to look up the slug in the backend.  This no longer works.  The API request, will, however, return the assigned Badgr slug and id (IRI) in the Response so we can store this value on the BadgeClass.

...

We will need to implement a data migration for existing BadgeClass objects to populate the new backend id field since the slug field is no longer a reliable future-proof identifier.   The migration will involve a call to the backend API.  


(new) Change how course completion badges are found

Currently, when a user is granted a certificate, a course complete badge is looked up by querying by a slug that must be in a very specific format derived from a hash of the course key and mode.  If a user tries to set up a BadgeClass manually via the Django Admin and picks a common sense slug, course completion badge awarding will fail.   The only way a Badge Class would be created with a slug in that format currently needed is if it is automatically created after a certificate event, in which case the Badge image used will be a generic image for an enrollment mode.  Most users outside of edX will wish to manually create their Badge Classes and use their own badge image related to a course or educational goal.  Many will wish to first create a Badge Class in the backend, then copy over the details to the LMS Django admin.   

...

  1. Currently, BadgeClass objects are unique by combination of course id, issuing component, and slug.  Instead I propose that a slug should be unique on its own, and that one BadgeClass per combination of course id and course mode should be allowed.  It makes sense Course A could have a separate badge for honor students and verified students.  Or, with a blank mode field, all Course A certificate earners should be awarded the same badge.  
  2. When a certificate is awarded for a course, the matching BadgeClass should be found by the course id combined with the student's enrollment mode.  Slug would not be used as a lookup unless passed explicitly.

(new) Change how course group, completion, and enrollment badges are found

Currently, lookups to the course group, courses completed and enrollment configuration objects are filtered on Issuing Component = 'openedx__course'.  I'm not sure that's necessary.  With my proposed changes, a Badge Class slug will be unique and can be used as the key for which slug to award.  Requiring a specific Issuing Component value would be redundant in terms of ensuring uniqueness.

(new) Store Issuing Component as tag on backend Badge Class

The Open edX badges app has the concept of Issuing Component.  This will no longer be part of a backend id, but is a potentially useful concept for distinguishing between course-scoped (Issuing Component="openedx__course") BadgeClasses and possible other scopes (e.g., Issuing Component="openedx__xseries").  A potential future Studio UI for Badge Class creation might support the automatic assignment of appropriate Issuing Component values. 

...