Background
openedx-core is adding a new top-level Django app, openedx_learning, whose first applet
(cbe) holds the Competency-Based Education models. Its first model,
CompetencyTaxonomy, is a Django multi-table-inheritance subclass of openedx_tagging's
Taxonomy that marks a taxonomy as competency-enabled.
That app is inert in a real deployment until this repo registers it: no table is created
and the model is never loaded. This issue covers the platform-side wiring.
Upstream work this depends on:
What to do
1. Register the app. Add "openedx_learning" to INSTALLED_APPS in both
lms/envs/common.py and cms/envs/common.py, alongside the existing "openedx_catalog"
and "openedx_content" entries.
2. Add the model to .annotation_safe_list.yml:
openedx_learning.CompetencyTaxonomy:
".. no_pii:": "No PII"
This is required even though the model carries an inline .. no_pii: annotation
upstream. This repo's .pii_annotations.yml sets source_path: ./, so the annotation
scan only reads this repo's tree and never looks inside installed site-packages. Every
openedx-core model is safelisted here for the same reason — openedx_content.PublishableEntity
is annotated inline upstream and still needs an entry here. Without it, pii_check drops
below its 100% coverage target.
3. Bump the openedx-core pin in requirements/edx/kernel.in and
requirements/edx/base.txt to a released version that contains the new app.
4. Add "openedx_learning" to the isolated_apps import-linter contract in
pyproject.toml, alongside the existing openedx_catalog entry. That contract limits
imports to api, models_api, data, and tests, keeping platform code off the app's
internals.
Item 4 carries more weight than usual here. Studio detects a competency taxonomy by
checking for a related CompetencyTaxonomy row on a Taxonomy, per the competency
taxonomy detection decision recorded in openedx-core. The name of that relation is a
Django-generated default, and hardcoding it in this repo would mean a rename upstream
breaks Studio with nothing failing in either repo's tests. openedx-core therefore
encapsulates it behind two public functions, and platform code should call those:
from openedx_learning.api import is_competency_taxonomy, select_competency_taxonomies
Pair them when checking more than one taxonomy — select_competency_taxonomies() joins
the child rows in so is_competency_taxonomy() costs no extra query per row. The
import-linter contract makes using the public API mechanical rather than a convention.
Ordering constraint
openedx/openedx-core#640 must merge and be released before this lands. If
INSTALLED_APPS names a module that is not installed, every management command fails.
Acceptance criteria
Out of scope
The REST API change that reports a taxonomy_type value on the taxonomy GET endpoints.
That is separate work built on top of this registration.
Background
openedx-core is adding a new top-level Django app,
openedx_learning, whose first applet(
cbe) holds the Competency-Based Education models. Its first model,CompetencyTaxonomy, is a Django multi-table-inheritance subclass ofopenedx_tagging'sTaxonomythat marks a taxonomy as competency-enabled.That app is inert in a real deployment until this repo registers it: no table is created
and the model is never loaded. This issue covers the platform-side wiring.
Upstream work this depends on:
CompetencyTaxonomymodelWhat to do
1. Register the app. Add
"openedx_learning"toINSTALLED_APPSin bothlms/envs/common.pyandcms/envs/common.py, alongside the existing"openedx_catalog"and
"openedx_content"entries.2. Add the model to
.annotation_safe_list.yml:This is required even though the model carries an inline
.. no_pii:annotationupstream. This repo's
.pii_annotations.ymlsetssource_path: ./, so the annotationscan only reads this repo's tree and never looks inside installed site-packages. Every
openedx-core model is safelisted here for the same reason —
openedx_content.PublishableEntityis annotated inline upstream and still needs an entry here. Without it,
pii_checkdropsbelow its 100% coverage target.
3. Bump the
openedx-corepin inrequirements/edx/kernel.inandrequirements/edx/base.txtto a released version that contains the new app.4. Add
"openedx_learning"to theisolated_appsimport-linter contract inpyproject.toml, alongside the existingopenedx_catalogentry. That contract limitsimports to
api,models_api,data, andtests, keeping platform code off the app'sinternals.
Item 4 carries more weight than usual here. Studio detects a competency taxonomy by
checking for a related
CompetencyTaxonomyrow on aTaxonomy, per the competencytaxonomy detection decision recorded in openedx-core. The name of that relation is a
Django-generated default, and hardcoding it in this repo would mean a rename upstream
breaks Studio with nothing failing in either repo's tests. openedx-core therefore
encapsulates it behind two public functions, and platform code should call those:
Pair them when checking more than one taxonomy —
select_competency_taxonomies()joinsthe child rows in so
is_competency_taxonomy()costs no extra query per row. Theimport-linter contract makes using the public API mechanical rather than a convention.
Ordering constraint
openedx/openedx-core#640 must merge and be released before this lands. If
INSTALLED_APPSnames a module that is not installed, every management command fails.Acceptance criteria
openedx_learningis inINSTALLED_APPSfor both LMS and CMSopenedx_learning.CompetencyTaxonomyis in.annotation_safe_list.yml, andmake pii_checkpasses at 100% coverageopenedx-corepin resolves to a version containing theopenedx_learningappmake check_migrationspasses and the app's migration applies cleanlyopenedx_learningis in theisolated_appscontract andlint-importspassesOut of scope
The REST API change that reports a
taxonomy_typevalue on the taxonomy GET endpoints.That is separate work built on top of this registration.