In a world where course teams change content, including removing/adding blocks, the following options allow learners to see different snapshots (versions) of the course content based on which version they initially interacted with, and thus, locked in.
Option 1. Expose versions from the modulestore and access version-specific data
Allow access to older versions of the course.
Persist the course's version number along with the learner's submission.
Continue to use the granularity of subsections to pin down the version number.
Or consider the granularity of verticals if we want to be more fine-grained.
To avoid race conditions, capture the version number at the time of rendering the problem.
Update the modulestore interface to:
return the version number of the returned block
take (an older) version number as an optional parameter and return that version of the block (only in the Published branch as read-only data).
Note: This is the most preferred option since it makes use of the versioning technology inherently available and using it for the purpose it was originally built.
Option 2. For each graded subsection, store required information of all scored sub-components, and only soft-delete blocks
Along with a subsection's grade, also store all metadata about the subsection's subtree that is needed to re-compute the subsection's grade. This includes
block-ids, weights, max_scores of all scorable (has_score=True) blocks within the subtree that are accessible by the user