Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .annotation_safe_list.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ openedx_content.Unit:
".. no_pii:": "This model has no PII"
openedx_content.UnitVersion:
".. no_pii:": "This model has no PII"
openedx_learning.HistoricalCompetencyCriteriaGroup:
".. no_pii:": "This model has no PII"
openedx_learning.HistoricalCompetencyCriterion:
".. no_pii:": "This model has no PII"
openedx_learning.HistoricalCompetencyRuleProfile:
".. no_pii:": "This model has no PII"
social_django.Association:
".. no_pii:": "This model has no PII"
social_django.Code:
Expand Down
11 changes: 10 additions & 1 deletion .importlinter
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
root_packages =
openedx_learning
openedx_content
openedx_catalog
openedx_tagging
openedx_django_lib
openedx_core
Expand All @@ -23,8 +24,16 @@ layers =
# particular, openedx_tagging must never know that CBE exists.
openedx_learning

# Content: authoring-side models and APIs.
# Content (authoring-side models and APIs) above Catalog (CatalogCourse/CourseRun):
# docs/openedx_learning/decisions/0007-pathway-catalog-content-split.rst ("Dependency
# direction: openedx_content knows about openedx_catalog, never the reverse") settles this
# direction, even though that ADR is still Draft rather than Accepted. A `layers` contract is
# a strict total order, and ranking them asserts only the half nobody disputes -- catalog
# never reaches up into content -- while still allowing the direction that ADR already
# depends on. CompetencyCriteriaGroup and CompetencyRuleProfile (openedx_learning) scope to a
# CourseRun, so both still need to sit below openedx_learning.
openedx_content
openedx_catalog

# Tagging is very simple & fundamental. Should probably not depend on any other Django apps.
openedx_tagging
Expand Down
3 changes: 3 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ files =
[mypy-organizations.*]
follow_untyped_imports = True

[mypy-simple_history.*]
follow_untyped_imports = True

[mypy.plugins.django-stubs]
django_settings_module = "projects.dev"
6 changes: 6 additions & 0 deletions projects/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@
# Open edX Organizations (dependency for openedx_catalog)
"organizations",

# django-simple-history: registers its template tag libraries and admin integration
# (SimpleHistoryAdmin) and its management commands (populate_history, clean_old_history,
# clean_duplicate_history). HistoricalRecords() works without this app installed, but nothing
# else it provides does, and the package ships no AppConfig or system check to warn you.
"simple_history",

# Our Apps
"openedx_catalog",
"openedx_learning",
Expand Down
2 changes: 2 additions & 0 deletions requirements/base.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ rules<4.0 # Django extension for rules-based authorization check
tomlkit # Parses and writes TOML configuration files

edx-organizations # Implemented the "Organization" model that CatalogCourse/CourseRun are keyed to

django-simple-history # History tracking for CBE criteria definitions, per ADR-0003
4 changes: 3 additions & 1 deletion requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ django-crum==0.7.9
django-model-utils==5.0.0
# via edx-organizations
django-simple-history==3.13.0
# via edx-organizations
# via
# -r requirements/base.in
# edx-organizations
django-waffle==5.0.0
# via
# edx-django-utils
Expand Down
15 changes: 15 additions & 0 deletions src/openedx_learning/applets/cbe/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
Models for Competency-Based Education (CBE).
"""

from .competency_taxonomy import CompetencyTaxonomy
from .criteria import CompetencyCriteriaGroup, CompetencyCriterion, CompetencyRuleProfile, LogicOperator, RuleType

__all__ = [
"CompetencyTaxonomy",
"CompetencyCriteriaGroup",
"CompetencyCriterion",
"CompetencyRuleProfile",
"LogicOperator",
"RuleType",
]
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""
Models for Competency-Based Education (CBE).
The CompetencyTaxonomy model.
"""
from django.db import models
from django.utils.translation import gettext_lazy as _

from openedx_tagging.models import Taxonomy

__all__ = [
Expand Down Expand Up @@ -35,6 +38,17 @@ class CompetencyTaxonomy(Taxonomy):
.. no_pii:
"""

taxonomy_overrides_org = models.BooleanField(
default=False,
help_text=_(
"Resolves a tie when assigning a CompetencyRuleProfile to a CompetencyCriterion (ADR-0002 "
"Decision 4): if both an organization-scoped profile and a taxonomy-scoped profile from this "
"taxonomy apply to the same criterion, False (the default) assigns the organization-scoped "
"profile, and True assigns this taxonomy's own profile instead, so it cannot be locally "
"weakened by an organization."
),
)

class Meta:
verbose_name = "Competency Taxonomy"
verbose_name_plural = "Competency Taxonomies"
Loading