Skip to content
Merged
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
16 changes: 16 additions & 0 deletions src/openedx_learning/applets/cbe/models/criteria.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ class CompetencyCriteriaGroup(models.Model):
"logic is moot; the application layer treats null the same as OR."
),
)
archived = models.BooleanField(
default=False,
help_text=_(
"Set instead of deleting this group once learner status exists for it or anything beneath "
"it. Hides the group from authoring and new associations while keeping it queryable, so its "
"criteria and existing learner status rows stay resolvable."
),
)
Comment on lines +99 to +106

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please describe what the flag means for the row rather than what one endpoint does with it. The "criteria-tree read endpoint" is #681, which doesn't exist yet, and it's one consumer among several: #674 and #675 are what set this, and #847's create_leaf_group() is going to have to care about it too. ADR-0002 Decision 2 already has the words, and CompetencyRuleProfile.archived below uses them. Maybe something like:

Suggested change
archived = models.BooleanField(
default=False,
help_text=_("Hides this row from the criteria-tree read endpoint by default, without removing it."),
)
archived = models.BooleanField(
default=False,
help_text=_(
"Set instead of deleting this group once learner status exists for it or anything beneath "
"it. Hides the group from authoring and new associations while keeping it queryable, so its "
"criteria and existing learner status rows stay resolvable."
),
)

Django bakes help_text into the migration, so 0014 needs regenerating after this. FYI @tbain: the same note applies to the archived fields in #856.


history = HistoricalRecords()

Expand Down Expand Up @@ -307,6 +315,14 @@ class CompetencyCriterion(models.Model):
null=True, blank=True,
help_text=_("Overrides rule_profile's rule_payload for this criterion. Set only when rule_profile is null."),
)
archived = models.BooleanField(
default=False,
help_text=_(
"Set instead of deleting this criterion once learner status exists for it. Hides the "
"criterion from authoring and new associations while keeping it queryable, so existing "
"learner status rows stay resolvable."
),
)
Comment on lines +318 to +325

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise here. Maybe:

Suggested change
archived = models.BooleanField(
default=False,
help_text=_("Hides this row from the criteria-tree read endpoint by default, without removing it."),
)
archived = models.BooleanField(
default=False,
help_text=_(
"Set instead of deleting this criterion once learner status exists for it. Hides the "
"criterion from authoring and new associations while keeping it queryable, so existing "
"learner status rows stay resolvable."
),
)


history = HistoricalRecords()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Generated by Django 5.2.17 on 2026-10-12 14:50

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
(
"openedx_learning",
"0013_alter_historicalcompetencycriteriagroup_history_date_and_more",
),
]

operations = [
migrations.AddField(
model_name="competencycriteriagroup",
name="archived",
field=models.BooleanField(
default=False,
help_text="Set instead of deleting this group once learner status exists for it or anything beneath it. Hides the group from authoring and new associations while keeping it queryable, so its criteria and existing learner status rows stay resolvable.",
),
),
migrations.AddField(
model_name="competencycriterion",
name="archived",
field=models.BooleanField(
default=False,
help_text="Set instead of deleting this criterion once learner status exists for it. Hides the criterion from authoring and new associations while keeping it queryable, so existing learner status rows stay resolvable.",
),
),
migrations.AddField(
model_name="historicalcompetencycriteriagroup",
name="archived",
field=models.BooleanField(
default=False,
help_text="Set instead of deleting this group once learner status exists for it or anything beneath it. Hides the group from authoring and new associations while keeping it queryable, so its criteria and existing learner status rows stay resolvable.",
),
),
migrations.AddField(
model_name="historicalcompetencycriterion",
name="archived",
field=models.BooleanField(
default=False,
help_text="Set instead of deleting this criterion once learner status exists for it. Hides the criterion from authoring and new associations while keeping it queryable, so existing learner status rows stay resolvable.",
),
),
]
12 changes: 12 additions & 0 deletions tests/openedx_learning/applets/cbe/test_criteria_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@
pytestmark = pytest.mark.django_db


# ---------------------------------------------------------------------------------------------
# Columns


# ---------------------------------------------------------------------------------------------


def test_group_archived_defaults_to_false(tag: Tag) -> None:
group = CompetencyCriteriaGroup.objects.create(tag=tag)
assert group.archived is False


# ---------------------------------------------------------------------------------------------
# Tree shape, and the two constraints ADR-0002 Decision 2 deliberately leaves out

Expand Down
16 changes: 16 additions & 0 deletions tests/openedx_learning/applets/cbe/test_criterion.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,22 @@
]


# ---------------------------------------------------------------------------------------------
# Columns


# ---------------------------------------------------------------------------------------------


def test_criterion_archived_defaults_to_false(
group: CompetencyCriteriaGroup, object_tag: ObjectTag, default_rule_profile: CompetencyRuleProfile
) -> None:
criterion = CompetencyCriterion.objects.create(
group=group, object_tag=object_tag, rule_profile=default_rule_profile
)
assert criterion.archived is False


# ---------------------------------------------------------------------------------------------
# Either a rule_profile or both overrides. Never both, never neither.

Expand Down
Loading