Backend: Course assignment models and sync considerations
❌ This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.
Overview
Create models for course assignments to support coaches assigning courses to learners and learner groups.
Tentative Model Structure
Based on existing patterns from Lesson and LessonAssignment:
from morango.models import UUIDField
class CourseAssignment(AbstractFacilityDataModel):
"""
Links a course ContentNode to Collections (Classroom or LearnerGroup)
"""
# UUID reference to the course ContentNode (not FK due to sync constraints)
course = UUIDField()
# The Collection (Classroom or LearnerGroup) assigned to
collection = models.ForeignKey(Collection, ...)
# Who made the assignment
assigned_by = models.ForeignKey(FacilityUser, ...)
# Whether the assignment is active/visible
is_active = models.BooleanField(default=False)
# Permissions (coach/admin can create/read/update/delete)
permissions = RoleBasedPermissions(
target_field="collection",
can_be_created_by=(role_kinds.ADMIN, role_kinds.COACH),
can_be_read_by=(role_kinds.ADMIN, role_kinds.COACH),
can_be_updated_by=(role_kinds.ADMIN, role_kinds.COACH),
can_be_deleted_by=(role_kinds.ADMIN, role_kinds.COACH),
)
# Morango fields
morango_model_name = "courseassignment"
Why UUIDField instead of ForeignKey: ContentNodes are not synced with facility data, so a foreign key would fail referential integrity checks during sync. Using UUIDField allows the assignment to exist even if the course content isn't currently available on a device.
Questions to Answer
Primary Question: Sync Scope
Should course assignments sync with full facility metadata, or use collection-based selective syncing?
- Full facility sync: All course assignments for a facility sync together (simpler, current default)
- Collection-based sync: Only sync assignments for collections a user is a member of (requires Morango updates)
Collection-based syncing would require:
- Updates to Morango to make synced data dependent on user's collection membership
- More complex partition/filter logic
- Better performance and privacy for large multi-classroom facilities
Secondary Questions
-
Redundant metadata storage: Should we store course title, channel_id, content_id for offline/sync scenarios where the course ContentNode isn't available?
-
Missing course handling: What should the UI show when a CourseAssignment references a course that isn't available on the device?
-
Assignment limits: Should there be constraints on number of active course assignments per classroom?
-
Morango partitioning: How should
calculate_partition()work - by dataset_id or collection_id?
References
- Existing models:
kolibri/core/lessons/models.py - Assignment patterns:
kolibri/core/content/utils/assignment.py - Morango UUIDField:
morango.models.fields.UUIDField