Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions docs/decisions/0022-tag-mutability-and-identity.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
22. Mutability and Identity of Taxonomy Tags
============================================

Status
------
Accepted

Context
-------

Taxonomy tags currently rely on three different identifiers, each serving a distinct purpose:
1. 'id': The internal, environment-specific database primary key.
2. 'value': A string used for display, search indexing, and short-lived API interactions (unique within a taxonomy).
3. 'external_id': A string used to track tag identity across system boundaries, particularly during long-lived use cases like course imports and exports.

Currently, the system implicitly treats 'external_id' as immutable. The architectural tension arises when an 'external_id' legitimately needs to change—for example, to correct a typo or to align with an upstream terminology change (e.g., updating an external standard from "equity considerations" to "use considerations").

If 'external_id' is strictly immutable, a user must delete the existing tag and create a new one, thereby destroying all existing object associations (foreign keys) tied to that tag.

Conversely, if we allow 'external_id' to be mutable, we break the mechanism used to maintain continuity during import/export workflows. Since internal database ''id''s cannot be used across different environments (as they are auto-incremented and environment-specific), the system would have no reliable way to map an incoming updated tag to the existing tag in the database.

The core architectural problem is: **How do we uniquely identify tags across decoupled environments while allowing administrators to mutate both display values and external identifiers without destroying existing data relationships?**

Decisions (Draft)
-----------------

1. Role and Scope of Identifiers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To maintain clean boundaries between internal systems and external data mobility, the roles of our identifiers must be strictly defined:

* **Internal Database 'id':** Strictly reserved for internal, environment-specific relational mapping. It will not be exposed in import/export payloads, as it lacks cross-environment portability.
* **'value':** Serves as the mutable, human-readable label. It remains unique within a taxonomy to facilitate hierarchical search indexing, but is not relied upon as a stable identifier for import/export.
* **'external_id':** Serves as the primary key for cross-environment synchronization (import/export).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this line would be clearer if instead it said something like "Serves as the primary key for cross-environment syncrhonization (import/export) of tags within the Taxonomy itself (not import/export of a course's associations to the taxonomy/tags)."


2. Handling Identifier Mutability
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* The taxonomy editor UI displays external IDs, but doesn't allow changing them. It may allow specifying them when creating a tag, and/or generate one based on the value if none is specified.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't how the taxonomy editor is functioning today. Are there intentions for it to function this way in the near future or should this bullet point be deleted? I think currently when new tags are created in the UI, the external_id for them is automatically generated as a copy of the value, iirc. And the external_id isn't displayed in the UI at all, from what I recall.

* In the rare case where an external ID needs to be changed, that can be easily done by an administrator using the Django admin UI.