Skip to content

feat!: Consistently attribute changes with time and author#573

Draft
kdmccormick wants to merge 3 commits intomainfrom
kdmccormick/timestamp-and-author
Draft

feat!: Consistently attribute changes with time and author#573
kdmccormick wants to merge 3 commits intomainfrom
kdmccormick/timestamp-and-author

Conversation

@kdmccormick
Copy link
Copy Markdown
Member

@kdmccormick kdmccormick commented Apr 29, 2026

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 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.

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.

@kdmccormick kdmccormick force-pushed the kdmccormick/timestamp-and-author branch from a55a1fe to 36143cc Compare April 29, 2026 20:57
@kdmccormick kdmccormick changed the base branch from main to kdmccormick/core-1 April 30, 2026 01:12
@kdmccormick kdmccormick force-pushed the kdmccormick/timestamp-and-author branch 3 times, most recently from ed6291c to 80d249a Compare April 30, 2026 03:50
@ormsbee ormsbee force-pushed the kdmccormick/core-1 branch from e0fa70b to 39e8088 Compare April 30, 2026 04:27
Base automatically changed from kdmccormick/core-1 to main April 30, 2026 04:33
kdmccormick and others added 3 commits April 30, 2026 01:22
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>
@kdmccormick kdmccormick force-pushed the kdmccormick/timestamp-and-author branch from c1307ef to eb255b2 Compare April 30, 2026 05:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant