Skip to content

The Big Keys Rework#527

Draft
kdmccormick wants to merge 6 commits intomainfrom
kdmccormick/keys
Draft

The Big Keys Rework#527
kdmccormick wants to merge 6 commits intomainfrom
kdmccormick/keys

Conversation

@kdmccormick
Copy link
Copy Markdown
Member

WIP

@kdmccormick kdmccormick force-pushed the kdmccormick/keys branch 3 times, most recently from 01a4091 to 16801f1 Compare April 2, 2026 19:25
kdmccormick and others added 5 commits April 2, 2026 16:58
Also, standardize internal usage of collection_key to collection_code.
This helps clarify that Collection.key is *not* an OpaqueKey, but is rather
a local slug, which can be combined with other identifiers to form a fully-
qualified LibraryCollectionKey instance.

BREAKING CHANGE: Collection.key has been renamed to Collection.collection_code.

BREAKING CHANGE: Collection.collection_code now validates that its contents
matches '[A-Za-z0-9\-\_\.]+'.  This was already effectively true, because
LibraryCollectionKey can only be built with slug-like parts, but we now
we explicitly raise ValiationError from create_collection.

Backup now writes both 'key' and 'collection_code' to collection TOML files,
so older software (which only knows 'key') can still read new archives.
Restore accepts either field, preferring 'collection_code' and falling back
to the legacy 'key'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Part of: #322
Renames the Component.local_key field to component_code, switching
from key_field() to code_field() (stricter validation: [A-Za-z0-9\-\_\.]+,
max_length=255). Updates all API call sites, backup/restore, and tests.

Backup/restore now writes an [entity.component] section in each component
TOML file containing component_type and component_code explicitly, so that
restore does not need to parse the entity key. Old archives (without the
[entity.component] section) are still accepted by falling back to the
existing entity key parsing.

BREAKING CHANGE: Component.local_key has been renamed to Component.component_code.

BREAKING CHANGE: Component.component_code now validates against
[A-Za-z0-9\-\_\.]+  and has a max_length of 255. Previously local_key
used key_field() (no regex validation, max_length=500).

BREAKING CHANGE: Function parameters renamed from local_key to component_code
in create_component(...) and create_component_and_version(...).

BREAKING CHANGE: Functions get_component_by_key(...)/component_exists_by_key(...),
renamed to get_component_by_code(...)/component_exists_by_code(...), and
parameters renamed from local_key to component_code.

Part of: #322

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a container_code field (code_field) and a learning_package FK to the
Container model. Also adds a UniqueConstraint on (learning_package,
container_code), which is stricter than Component's constraint
(no type scoping -- container codes must be unique across all container
types within a given LearningPackage).

For existing containers, container_code is backfilled from the entity key
via a data migration. Future containers will have container_code set
explicitly by the caller.

Backup/restore now writes container_code into the [entity.container]
section (Verawood and later). Archives created in Ulmo (which have no
container_code) fall back to using the entity key as the container_code
on restore.

BREAKING CHANGE: create_container() and create_container_and_version()
now require a container_code keyword argument. The same applies to
create_unit_and_version(), create_subsection_and_version(), and
create_section_and_version().

Part of: #322

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The `{LearningPackage,PublishableEntity}.key` fields were always
meant to be externally-supplied refs whose format does not matter.
However, they were effectively being used as parseable psuedo-keys
for identifying containers and components, with more assumptions to their
structure being baked in over time, both within and outside openedx-core.

This commit renames them to `{package,entity}_ref`, and removes all
parsing of them from the API and from the internals (except for where
required for backcompat with Ulmo ZIP backups). Instead, the pairings
of (component_type,component_code) and (container_type,container_code)
are used to identify components and containers; their respective
entity_refs are derived from those *by conventional default* but also
are customizable by callers.

BREAKING CHANGE: Renamed key_field(...) -> ref_field(...) in openedx_django_lib.

BREAKING CHANGE: Renamed PublishableEntity.key -> PublishableEntityKey.entity_ref
BREAKING CHANGE: Renamed PublishableEntityMixin.key -> PublishableEntityMixin.entity_ref
BREAKING CHANGE: In create_publishable_entity(...), renamed param key -> entity_ref
BREAKING CHANGE: Renamed get_publishable_entity_by_key(...) ->
  get_publishable_entity_by_ref(...), and renamed param key -> entity_ref
BREAKING CHANGE: In get_entity_collections(...), renamed param entity_key -> entity_ref
BREAKING CHANGE: In create_component(...)/create_container(...):
  * Positional key argument removed
  * Optional entity_ref argument added
  * Defaults to defaults to "{namespace}:{type_name}:{component_code}" if unspecified
BREAKING CHANGE: Function get_or_create_component_type_by_entity_key() removed.
BREAKING CHANGE: Rename get_container_children_entities_keys(...) ->
  get_container_children_entity_refs(...)
BREAKING CHANGE: Renamed get_container_by_key(...) -> get_container_by_ref(..)
  and renamed param key -> entity_ref.
BREAKING CHANGE: Renamed get_container_children_entities_keys(...) ->
  get_container_children_entity_refs(...)

BRAEKING CHANGE: Renamed LearningPackage.key -> LearningPackage.package_ref.
BREAKING CHANGE: In create_learning_package(...), renamed param key -> package_ref
BREAKING CHANGE: In update_learning_package(...), renamed param key -> package_ref
BREAKING CHANGE: Renamed get_learning_package_by_key(...) ->
  get_learning_package_by_ref(...), and renamed param key -> package_ref
BREAKING CHANGE: In learning_package_exists(...), renamed param key -> package_ref

BREAKING CHANGE: In look_up_component_version_media(...):
  * Renamed param learning_package_key -> learning_package_ref
  * Renamed param component_key -> entity_ref

BREAKING CHANGE: In add_assets_to_component management command:
  * Renamed argument learning_package_key -> learning_package_ref
  * Renamed argument component_key -> entity_ref

BREAKING CHANGE In load_learning_package:
  * Renamed  param key -> package_ref
  * In return dict, within sub-dict ["lp_restored_data"]:
    * Renamed ["key"] -> ["package_ref"]
    * Renamed ["archive_lp_key"] -> ["archive_package_ref"]
    * Renamed ["archive_org_key"] -> ["archive_org_code"]
    * Renamed ["archive_slug"] -> ["archive_package_code"]
  * If archive_package_ref cannot be parsed into "{_prefix}:{org_code}:{package_code}", then
    archvie_org_code and archive_package_code will both be None. Callers should handle this case.
    (Previously, a ValueError would be raised by backup-restore code.)

Backup/Restore format changes (non-breaking):
* In [learning_package], key field is renamed -> package_ref.
* In [entity], key field is renamed -> entity_ref.
* For compatibility with Ulmo instances, both key and {package,entity}_ref
  will be written in all new archives.
* For compatibility with Ulmo archives, both key and {package,entity}_ref
  will be read, with priority given to the latter.

Part of: #322

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
BREAKING CHANGE: Renamed ComponentVersionMedia.key -> ComponentVersionMedia.path
BREAKING CHANGE: In create_component_version_media(...) and
                 look_up_component_version_media(...), renamed param key -> path.

Part of: #322

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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