diff --git a/docs/openedx_learning/decisions/0004-pathway-catalog-content-split.rst b/docs/openedx_learning/decisions/0005-pathway-catalog-content-split.rst similarity index 99% rename from docs/openedx_learning/decisions/0004-pathway-catalog-content-split.rst rename to docs/openedx_learning/decisions/0005-pathway-catalog-content-split.rst index 262dbe5ad..4071cffec 100644 --- a/docs/openedx_learning/decisions/0004-pathway-catalog-content-split.rst +++ b/docs/openedx_learning/decisions/0005-pathway-catalog-content-split.rst @@ -1,4 +1,4 @@ -.. _openedx-learning-adr-0004: +.. _openedx-learning-adr-0005: 4. Pathways: Split Between Catalog and Content ============================================== diff --git a/docs/openedx_learning/decisions/0005-pathway-and-pathway-items.rst b/docs/openedx_learning/decisions/0006-pathway-and-pathway-items.rst similarity index 95% rename from docs/openedx_learning/decisions/0005-pathway-and-pathway-items.rst rename to docs/openedx_learning/decisions/0006-pathway-and-pathway-items.rst index 3d7c587b0..3b3234053 100644 --- a/docs/openedx_learning/decisions/0005-pathway-and-pathway-items.rst +++ b/docs/openedx_learning/decisions/0006-pathway-and-pathway-items.rst @@ -1,4 +1,4 @@ -.. _openedx-learning-adr-0005: +.. _openedx-learning-adr-0006: 5. Pathways: The Boundary Between Pathway and Pathway Item ========================================================== @@ -25,7 +25,7 @@ Decisions 2. A Pathway Item has its own identity and lifecycle. An Item may be fulfilled by one thing today (e.g. passing a course) and by something else tomorrow (e.g. a competency attainment, or an admin override) without changing its identity - and therefore without changing the Pathway that contains it. How fulfillment is modeled is a separate - decision (:ref:`openedx-learning-adr-0006`). + decision (:ref:`openedx-learning-adr-0007`). 3. Pathway to Item relationships do not break new ground structurally. We already have precedent for modeling parent-child relations in ``openedx_content`` containers; Pathway/PathwayItem will not use Container directly, @@ -35,7 +35,7 @@ Decisions fulfillment rules; the Pathway's completion is computed from Item completion. 5. In the MVP, Pathway completion is not configurable: a Pathway is complete when *all* of its Items are complete. - Because every Item is fulfilled by passing a course (:ref:`openedx-learning-adr-0006`), this means the learner has + Because every Item is fulfilled by passing a course (:ref:`openedx-learning-adr-0007`), this means the learner has passed every course in the Pathway, with grade and passed/failed state read directly from each course. Configurable criteria (e.g. "complete 4 of these 5 Items") are expected in later iterations, and the intent is for them to be expressed in terms of Item completion rather than the Pathway-specific definition of what fulfills each Item. diff --git a/docs/openedx_learning/decisions/0006-pathway-item-fulfillment.rst b/docs/openedx_learning/decisions/0007-pathway-item-fulfillment.rst similarity index 98% rename from docs/openedx_learning/decisions/0006-pathway-item-fulfillment.rst rename to docs/openedx_learning/decisions/0007-pathway-item-fulfillment.rst index 34dcbd26b..b69011156 100644 --- a/docs/openedx_learning/decisions/0006-pathway-item-fulfillment.rst +++ b/docs/openedx_learning/decisions/0007-pathway-item-fulfillment.rst @@ -1,4 +1,4 @@ -.. _openedx-learning-adr-0006: +.. _openedx-learning-adr-0007: 6. Pathways: Mapping Pathway Items to the Things That Fulfill Them ================================================================== @@ -11,7 +11,7 @@ Draft Context ------- -:ref:`openedx-learning-adr-0005` establishes that a Pathway Item is a stable requirement whose fulfillment can change +:ref:`openedx-learning-adr-0006` establishes that a Pathway Item is a stable requirement whose fulfillment can change over time. This ADR describes how we intend to map Items to the things that fulfill them, starting with the only fulfillment type in the first release: passing a course. diff --git a/docs/openedx_learning/decisions/0008-pathway-credentials.rst b/docs/openedx_learning/decisions/0008-pathway-credentials.rst new file mode 100644 index 000000000..043fbb825 --- /dev/null +++ b/docs/openedx_learning/decisions/0008-pathway-credentials.rst @@ -0,0 +1,65 @@ +.. _openedx-learning-adr-0008: + +7. Pathway Credentials +====================== + +Status +------ + +Draft + +Context +------- + +Learners who complete a Pathway should receive a certificate, in the same way as the built-in Open edX course +certificates. Individual courses inside a Pathway keep their existing course certificates unchanged; this decision is +only about the Pathway-level credential. + +Decisions +--------- + +1. **Earning rule.** A learner earns the Pathway certificate by fulfilling all Items in the Pathway. In the MVP that + means passing every course in the Pathway, where "passing" is dictated by each course's own grading policy. There + are no Pathway-level grades, thresholds, or enrollment modes. + +2. **Automatic issuance via signals.** The Pathways app listens for the Django signals the platform already emits when + a learner's course passing status changes. On each relevant signal, it re-evaluates the learner's Item fulfillment + for any enrolled Pathways containing that course, and issues the certificate as soon as all Items are fulfilled. + No manual issuing step is required. + +3. **Configuration in Django admin.** Pathway certificates are configured in the Django admin, not in Studio. A + certificate configuration can be created, previewed, edited, and deleted while inactive; it must be activated + before certificates are issued. Configuration includes the issuing organization and 1–4 signatories (name, title, + organization, signature image). + +4. **Rendering.** An issued certificate is rendered as an HTML page (printable by the learner), analogous to course + certificates. No W3C Verifiable Credentials / Open Badges support in Willow. + +5. **What a certificate is a claim about.** A certificate ties a learner to a specific version of the Pathway + content: the versioned side of the split described in :ref:`openedx-learning-adr-0005`, because a certificate + asserts that a particular Pathway completion definition was met. The Catalog Pathway is not recorded separately. + Instead, it follows from the content version. + +6. **Issued certificates are records.** Alongside that reference, a certificate stores a snapshot of everything + needed to display it later: recipient name, Pathway name, issuer, signatories, the criteria met (the list of + courses passed), and the date earned. The snapshot is for rendering; the version reference is the authoritative + part. A certificate remains valid and viewable even if the Pathway is later updated or archived. + +7. **Events.** Issuing a certificate emits an event, so that instances can report on credentials (e.g. in Aspects). + It also sends an email to the learner, with a link to view the certificate. + +.. Run `dot -Tsvg images/pathway-credentials.dot > images/pathway-credentials.svg` to regenerate the diagram after + making changes to `images/pathway-credentials.dot`. + +.. image:: images/pathway-credentials.svg + :alt: Pathway certificate issuance flow + :width: 100% + +Consequences +------------ + +- Because issuance uses the existing platform signals, no polling or batch jobs are needed for the typical flow. +- Since certificates are self-contained records, later edits to the Pathway or its certificate configuration never + alter what a learner already earned. +- Interaction-progress-based criteria, per-course credential rules, badges/microcredentials, and verifiable + credentials are all explicitly out of scope and can be layered on later without changing the basics of this design. diff --git a/docs/openedx_learning/decisions/images/pathway-credentials.dot b/docs/openedx_learning/decisions/images/pathway-credentials.dot new file mode 100644 index 000000000..1a16c34f2 --- /dev/null +++ b/docs/openedx_learning/decisions/images/pathway-credentials.dot @@ -0,0 +1,18 @@ +digraph pathway_credentials { + rankdir=LR; + fontname="Helvetica"; + node [shape=box, style=rounded, fontname="Helvetica", fontsize=11]; + edge [fontname="Helvetica", fontsize=10]; + + signal [label="course passing-status\nDjango signal", shape=ellipse]; + handler [label="re-evaluate Item fulfillment\nfor learner's enrolled Pathways\ncontaining that course"]; + decide [label="all Items\nfulfilled?", shape=diamond, style=""]; + issue [label="issue certificate:\nstore self-contained record,\nemit event"]; + render [label="HTML certificate\n(viewable, printable)"]; + + signal -> handler -> decide; + decide -> issue [label="yes"]; + decide -> done [label="no"]; + done [label="done", shape=plaintext]; + issue -> render; +} diff --git a/docs/openedx_learning/decisions/images/pathway-credentials.svg b/docs/openedx_learning/decisions/images/pathway-credentials.svg new file mode 100644 index 000000000..387524871 --- /dev/null +++ b/docs/openedx_learning/decisions/images/pathway-credentials.svg @@ -0,0 +1,87 @@ + + + + + + +pathway_credentials + + + +signal + +course passing-status +Django signal + + + +handler + +re-evaluate Item fulfillment +for learner's enrolled Pathways +containing that course + + + +signal->handler + + + + + +decide + +all Items +fulfilled? + + + +handler->decide + + + + + +issue + +issue certificate: +store self-contained record, +emit event + + + +decide->issue + + +yes + + + +done +done + + + +decide->done + + +no + + + +render + +HTML certificate +(viewable, printable) + + + +issue->render + + + + +