feat!: Consistently attribute changes with time and author#573
Draft
kdmccormick wants to merge 3 commits intomainfrom
Draft
feat!: Consistently attribute changes with time and author#573kdmccormick wants to merge 3 commits intomainfrom
kdmccormick wants to merge 3 commits intomainfrom
Conversation
This was referenced Apr 29, 2026
a55a1fe to
36143cc
Compare
ed6291c to
80d249a
Compare
e0fa70b to
39e8088
Compare
This modifies the signatures of several API functions in openedx_content such that it is easier to correctly attribute operations to their author and datetime of change, and more difficult to forget to attribute them. BREAKING CHANGE: The `with bulk_draft_changes_for(...):` context manager is renamed `with draft_changes_for(...):`. Furthermore, to encourage callers to correctly associate DraftChangeLogs with their author users whenever possible, the `changed_by=` param is now required (although callers can explicitly pass `changed_by=None` for operations which are truly author-less, like data backfills). Finally, the `changed_at=` param remains optional, but its default value has changed from `None` to `DATETIME_AUTO` and `None` is forbidden; this is just a signature change—as was the default behavior before, `DATETIME_AUTO` will resolve to the current time. This reflects its expanded role: BREAKING CHANGE: Functions which generate DraftChanges may now *only* occur within a `draft_changes_for` context, even if they are single operations (hence the dropping of the `bulk_` prefix from the context manager's name). Furthermore, these functions no longer accept authorship params (`created_by=`, `changed_by=`, etc.) nor datetime params (`created=`, `created_at=`, `changed=`, `changed_at=`, etc.). Instead, they will inherit these values from their enclosing `draft_changes_for(...)` context. The affected functions are: * create_publishable_entity_version * reset_drafts_to_published * soft_delete_draft * set_draft_version * create_(component|container)_version * create_(component|container)_and_version * create_next_(component|container)_version * create_(unit|subsection|section)_and_version * create_next_(unit|subsection|section)_version BREAKING CHANGE: Functions which create or edit versionless content objects (i.e., those which don't generate DraftChanges) may continue to be used inside or outside of `draft_changes_for` contexts, but the default behavior of each function's authorship param (`created_by=`, `changed_by`, etc.) has changed. Previously, it would default to `None` (no author attribution). Now, it defaults to a new sentinel value, `AUTHOR_AUTO`. Within a context, `AUTHOR_AUTO` resolves to the author of the enclosing context. Outside of a context, an exception is raised unless the default `AUTHOR_AUTO` param is specified as something else—either a specific user, or an explicit `None` to indicate a special author-less operation such as a data backfill. Finally, the default of these operations' datetime params (`created=`, `created_at=`, `changed_at`, etc.) is now `DATETIME_AUTO`, paralleling `draft_changes_for(...)`. The affected functions are: * create_publishable_entity * create_(component|container) * create_collection * set_collections BREAKING CHANGE: A couple other functions with `created` params now default to `DATETIME_AUTO` and forbid `None`. They are: * create_learning_package * update_learning_package BREAKING CHANGE: `publish_all_drafts(...)` and `publish_from_drafts(...)` now require the caller to specify `published_by` (a User, user ID, AnonymousUser, or explicit `None`). To match the rest of this rework, `published_at=` now defaults to `DATETIME_AUTO` (resolving to the current time when called outside a `draft_changes_for` context, which is required for these functions). Additionally, `message=`, `published_at=`, and `publish_dependencies=` are now keyword-only. BREAKING CHANGE: `set_collections(...)` now accepts a `created=` timestamp (stored on the m2m through-table along with `created_by`). Both `created=` and `created_by=` are keyword-only and follow the `AUTHOR_AUTO`/`DATETIME_AUTO` defaults described above. Part of: #549
Co-Authored-By: Claude Opus 4.7 1M Context <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
c1307ef to
eb255b2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
feat!: Consistently attribute changes with time and author
This modifies the signatures of several API functions in openedx_content
such that it is easier to correctly attribute operations to their author and
datetime of change, and more difficult to forget to attribute them.
BREAKING CHANGE: The
with bulk_draft_changes_for(...):context manager isrenamed
with draft_changes_for(...):. Furthermore, to encourage callers tocorrectly associate DraftChangeLogs with their author users whenever possible,
the
changed_by=param is now required (although callers can explicitly passchanged_by=Nonefor operations which are truly author-less, like databackfills). Finally, the
changed_at=param remains optional, but its defaultvalue has changed from
NonetoDATETIME_AUTOandNoneis forbidden; thisis just a signature change—as was the default behavior before,
DATETIME_AUTOwill resolve to the current time. This reflects its expanded role:
BREAKING CHANGE: Functions which generate DraftChanges may now only occur
within a
draft_changes_forcontext, even if they are single operations (hencethe dropping of the
bulk_prefix from the context manager's name).Furthermore, these functions no longer accept authorship params (
created_by=,changed_by=, etc.) nor datetime params (created=,created_at=,changed=,changed_at=, etc.). Instead, they will inherit these values fromtheir enclosing
draft_changes_for(...)context. The affected functions are:BREAKING CHANGE: Functions which create or edit versionless content objects
(i.e., those which don't generate DraftChanges) may continue to be used inside
or outside of
draft_changes_forcontexts, but the default behavior of eachfunction's authorship param (
created_by=,changed_by, etc.) has changed.Previously, it would default to
None(no author attribution). Now, itdefaults to a new sentinel value,
AUTHOR_AUTO. Within a context,AUTHOR_AUTOresolves to the author of the enclosing context. Outside of acontext, an exception is raised unless the default
AUTHOR_AUTOparam isspecified as something else—either a specific user, or an explicit
Nonetoindicate a special author-less operation such as a data backfill. Finally, the
default of these operations' datetime params (
created=,created_at=,changed_at, etc.) is nowDATETIME_AUTO, parallelingdraft_changes_for(...). The affected functions are:BREAKING CHANGE: A couple other functions with
createdparams nowdefault to
DATETIME_AUTOand forbidNone. They are:BREAKING CHANGE:
publish_all_drafts(...)andpublish_from_drafts(...)nowrequire the caller to specify
published_by(a User, user ID, AnonymousUser,or explicit
None). To match the rest of this rework,published_at=nowdefaults to
DATETIME_AUTO(resolving to the current time when calledoutside a
draft_changes_forcontext, which is required for these functions).Additionally,
message=,published_at=, andpublish_dependencies=are nowkeyword-only.
BREAKING CHANGE:
set_collections(...)now accepts acreated=timestamp(stored on the m2m through-table along with
created_by). Bothcreated=andcreated_by=are keyword-only and follow theAUTHOR_AUTO/DATETIME_AUTOdefaults described above.
Supporting info
Part of: #549
AI
First commit was all me. That's all the src/ changes, the majority of the commit message, and some starter test changes.
Claude (Opus 4.7 1M Context) did an audit and found some issues, fixed those in the second commit. It also suggested additional BREAKING CHANGES for my commit message.
Claude (Opus 4.6) fixed the remainder of the tests.