diff --git a/README.rst b/README.rst index 40e4b68d9..bc29f80da 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -Open edX Core: Foundational Packages for a Teaching & Learning Platform -======================================================================= +Open edX Core +============= |pypi-badge| |ci-badge| |codecov-badge| |doc-badge| |pyversions-badge| |license-badge| @@ -7,7 +7,7 @@ Open edX Core: Foundational Packages for a Teaching & Learning Platform Overview -------- -*Formerly known as "Learning Core" or "openedx-learning".* +**Foundational Packages for a Teaching & Learning Platform** (*formerly known as "Learning Core" or "openedx-learning"*) The ``openedx-core`` project holds Django apps which represent core teaching & learning platform concepts. @@ -31,7 +31,7 @@ Open edX Core Package Dependencies Open edX Core code should never import from ``openedx-platform``. -We want to be very strict about dependency management internally as well. Please read the `.importlinter config file <.importlinter>`_ file and the `Python API Conventions ADR `_ for more details. +We want to be very strict about dependency management internally as well. Please read the `.importlinter config file <.importlinter>`_ file and the `Python API Conventions ADR `_ for more details. Model Conventions diff --git a/docs/changelog.rst b/docs/changelog.rst deleted file mode 100644 index 565b0521d..000000000 --- a/docs/changelog.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../CHANGELOG.rst diff --git a/docs/conf.py b/docs/conf.py index 8153186e7..8f3602c79 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -35,7 +35,7 @@ def get_version(*file_paths): REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(REPO_ROOT) -VERSION = get_version('src/openedx_core', '__init__.py') +VERSION = get_version('../src/openedx_core', '__init__.py') # Configure Django for autodoc usage os.environ['DJANGO_SETTINGS_MODULE'] = 'test_settings' @@ -109,7 +109,7 @@ def get_version(*file_paths): # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = "en" # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: diff --git a/docs/decisions.rst b/docs/decisions.rst deleted file mode 100644 index e93f2360b..000000000 --- a/docs/decisions.rst +++ /dev/null @@ -1,12 +0,0 @@ -Decisions -========= - -The following `ADRs` are a record of all decisions made as a part of developing this library. - -.. _ADRs: https://open-edx-proposals.readthedocs.io/en/latest/oep-0019-bp-developer-documentation.html#adrs - -.. toctree:: - :maxdepth: 1 - :glob: - - decisions/* diff --git a/docs/index.rst b/docs/index.rst index 12ecd90e8..8ff88027d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,23 +3,21 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Open edX Core -============= +.. _openedx-core-index: -The boring, foundational bits of a learning platform that are hard to get right at scale. Currently being developed for content storage. - -Contents: +.. include:: ../README.rst .. toctree:: :maxdepth: 2 - readme - getting_started - testing - internationalization - changelog - api_reference - decisions + openedx_core/getting_started + openedx_core/testing + openedx_core/internationalization + openedx_core/decisions/index + + openedx_content/index + openedx_tagging/index + openedx_learning/index Indices and tables ================== diff --git a/docs/api_reference.rst b/docs/openedx_content/api_reference.rst similarity index 70% rename from docs/api_reference.rst rename to docs/openedx_content/api_reference.rst index b46ac15a2..97ea9ab87 100644 --- a/docs/api_reference.rst +++ b/docs/openedx_content/api_reference.rst @@ -1,3 +1,5 @@ +.. _openedx-content-api-reference: + API Reference ============= diff --git a/docs/decisions/0002-content-flexibility.rst b/docs/openedx_content/decisions/0001-content-flexibility.rst similarity index 98% rename from docs/decisions/0002-content-flexibility.rst rename to docs/openedx_content/decisions/0001-content-flexibility.rst index bf13e5c04..4660ea899 100644 --- a/docs/decisions/0002-content-flexibility.rst +++ b/docs/openedx_content/decisions/0001-content-flexibility.rst @@ -1,4 +1,6 @@ -2. Approach to Content Flexibility +.. _openedx-content-adr-0001: + +1. Approach to Content Flexibility ================================== Status diff --git a/docs/decisions/0003-content-extensibility.rst b/docs/openedx_content/decisions/0002-content-extensibility.rst similarity index 98% rename from docs/decisions/0003-content-extensibility.rst rename to docs/openedx_content/decisions/0002-content-extensibility.rst index 17b73b836..2a4fb3392 100644 --- a/docs/decisions/0003-content-extensibility.rst +++ b/docs/openedx_content/decisions/0002-content-extensibility.rst @@ -1,4 +1,6 @@ -3. Content Extensibility Through Model Relations +.. _openedx-content-adr-0002: + +2. Content Extensibility Through Model Relations ================================================ Context diff --git a/docs/decisions/0005-identifier-conventions.rst b/docs/openedx_content/decisions/0003-identifier-conventions.rst similarity index 97% rename from docs/decisions/0005-identifier-conventions.rst rename to docs/openedx_content/decisions/0003-identifier-conventions.rst index b7fe95c90..2f36d5b4e 100644 --- a/docs/decisions/0005-identifier-conventions.rst +++ b/docs/openedx_content/decisions/0003-identifier-conventions.rst @@ -1,4 +1,6 @@ -5. Identifier Conventions +.. _openedx-content-adr-0003: + +3. Identifier Conventions ========================= Status diff --git a/docs/decisions/0006-app-label-prefix.rst b/docs/openedx_content/decisions/0004-app-label-prefix.rst similarity index 72% rename from docs/decisions/0006-app-label-prefix.rst rename to docs/openedx_content/decisions/0004-app-label-prefix.rst index ad23d1b28..7a04f84f5 100644 --- a/docs/decisions/0006-app-label-prefix.rst +++ b/docs/openedx_content/decisions/0004-app-label-prefix.rst @@ -1,10 +1,12 @@ -6. App Label Prefix +.. _openedx-content-adr-0004: + +4. App Label Prefix =================== Status ------ -Obsolete. See decision 0020. Apps like ``openedx_content`` no longer use the ``oel_`` prefix, and this repo is no longer called "learning core". +Obsolete. See decision :ref:`openedx-content-adr-0010`. Apps like ``openedx_content`` no longer use the ``oel_`` prefix, and this repo is no longer called "learning core". Context ------- diff --git a/docs/decisions/0015-serving-static-assets.rst b/docs/openedx_content/decisions/0005-serving-static-assets.rst similarity index 99% rename from docs/decisions/0015-serving-static-assets.rst rename to docs/openedx_content/decisions/0005-serving-static-assets.rst index 969b40725..103b1a603 100644 --- a/docs/decisions/0015-serving-static-assets.rst +++ b/docs/openedx_content/decisions/0005-serving-static-assets.rst @@ -1,4 +1,6 @@ -15. Serving Course Team Authored Static Assets +.. _openedx-content-adr-0005: + +5. Serving Course Team Authored Static Assets ============================================== Context diff --git a/docs/decisions/0016-python-public-api-conventions.rst b/docs/openedx_content/decisions/0006-python-public-api-conventions.rst similarity index 98% rename from docs/decisions/0016-python-public-api-conventions.rst rename to docs/openedx_content/decisions/0006-python-public-api-conventions.rst index cb030f77f..86059094f 100644 --- a/docs/decisions/0016-python-public-api-conventions.rst +++ b/docs/openedx_content/decisions/0006-python-public-api-conventions.rst @@ -1,10 +1,12 @@ -16. Python Public API Conventions +.. _openedx-content-adr-0006: + +6. Python Public API Conventions ================================= Status ------ -Superseded by decision 0020. +Superseded by decision :ref:`openedx-content-adr-0010`. Context -------- diff --git a/docs/decisions/0017-generalized-containers.rst b/docs/openedx_content/decisions/0007-generalized-containers.rst similarity index 96% rename from docs/decisions/0017-generalized-containers.rst rename to docs/openedx_content/decisions/0007-generalized-containers.rst index 5840b3731..a7d417c59 100644 --- a/docs/decisions/0017-generalized-containers.rst +++ b/docs/openedx_content/decisions/0007-generalized-containers.rst @@ -1,4 +1,6 @@ -17. Modeling Containers as a Generalized Capability for Holding Content +.. _openedx-content-adr-0007: + +7. Modeling Containers as a Generalized Capability for Holding Content ======================================================================== Status @@ -50,8 +52,8 @@ This section defines container types, content constraints, hierarchy, and extens - Containers can be nested within other containers, allowing for complex content structures. For example, subsections can contain units. - Containers might be of different types, with each type potentially having different restrictions on the type of content it can hold but that will not be enforced by containers. - Content restrictions for containers are implemented at the app layer, allowing specific container types, like units, to limit their children to particular content types, e.g., units are restricted to contain only components. -- The course hierarchy Course > Section > Subsection > Unit will be implemented as relationships between containers, with each level acting as a container that holds other content. The hierarchy will be enforced by the content restrictions of each particular container but allowed to be overridden to support `Approach to Content Flexibility <0002-content-flexibility.rst>`_. -- Containers will follow extensibility principles in `Content Extensibility Through Model Relations <0003-content-extensibility.rst>`_ for creating new container types or subtypes. +- The course hierarchy Course > Section > Subsection > Unit will be implemented as relationships between containers, with each level acting as a container that holds other content. The hierarchy will be enforced by the content restrictions of each particular container but allowed to be overridden to support :ref:`openedx-content-adr-0001`. +- Containers will follow extensibility principles in :ref:`openedx-content-adr-0002` for creating new container types or subtypes. 3. Container Children and Relationships ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/decisions/0018-units-as-containers.rst b/docs/openedx_content/decisions/0008-units-as-containers.rst similarity index 90% rename from docs/decisions/0018-units-as-containers.rst rename to docs/openedx_content/decisions/0008-units-as-containers.rst index 0a3ed0646..8079ec445 100644 --- a/docs/decisions/0018-units-as-containers.rst +++ b/docs/openedx_content/decisions/0008-units-as-containers.rst @@ -1,4 +1,6 @@ -18. Modeling Units as a Concrete Implementation of the Container Capability +.. _openedx-content-adr-0008: + +8. Modeling Units as a Concrete Implementation of the Container Capability =========================================================================== Context @@ -9,7 +11,7 @@ The container capability is a generalized capability to hold different types of Decisions --------- -All decisions from `0017-generalized-containers.rst <0017-generalized-containers.rst>`_ are still valid but are written here alongside unit-specific decisions for better illustration. +All decisions from :ref:`openedx-content-adr-0007` are still valid but are written here alongside unit-specific decisions for better illustration. 1. Units as Containers ~~~~~~~~~~~~~~~~~~~~~~~ @@ -25,7 +27,7 @@ All decisions from `0017-generalized-containers.rst <0017-generalized-containers - Units can only hold components as their children but will not enforce this restriction at the model level. - Units are the first level of nested content types Unit > Components. - Content restrictions for units are implemented at the application layer, allowing units to limit their children to only components. None of this is enforced at the model level. -- Unit subtypes can be created by following the extensibility principles in `Content Extensibility Through Model Relations <0003-content-extensibility.rst>`_. +- Unit subtypes can be created by following the extensibility principles in :ref:`openedx-content-adr-0002`. 3. Unit Children and Relationships ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/decisions/0019-selectors.rst b/docs/openedx_content/decisions/0009-selectors.rst similarity index 94% rename from docs/decisions/0019-selectors.rst rename to docs/openedx_content/decisions/0009-selectors.rst index 118c2d4be..5258e13d0 100644 --- a/docs/decisions/0019-selectors.rst +++ b/docs/openedx_content/decisions/0009-selectors.rst @@ -1,4 +1,6 @@ -19. Selectors for Dynamically Selecting Content +.. _openedx-content-adr-0009: + +9. Selectors for Dynamically Selecting Content =============================================== Status @@ -35,7 +37,7 @@ This section explains the concepts and behaviors used to build dynamic selection This section describes how different types of selectors work and how they handle the selection of dynamic content. -- A selector can be of any type, which means it can implement any method to select members from a pool. Therefore, selectors will follow extensibility principles in `0003-content-extensibility.rst <0003-content-extensibility.rst>`_ for creating new selector types. +- A selector can be of any type, which means it can implement any method to select members from a pool. Therefore, selectors will follow extensibility principles in :ref:`openedx-content-adr-0002` for creating new selector types. - Selection versions encode the rules and holds useful details for the selection process like: where to get members from, number of items to select, and other criteria. For instance, for the "select 5 components out of this pool of 20 components" its selector version would encode where to get the 20 components, how many to get for each user and any other detail needed to create the specific variants. - Depending on the size of the pool of members, variants can be generated at publishing time or on-demand. This behavior should be determined by the selector version based on high vs low permutation scenarios. - A compositor is responsible for populating the variants but will not be implemented as part of the selector application which belongs to the authoring app. diff --git a/docs/decisions/0020-merge-authoring-apps-into-openedx-content.rst b/docs/openedx_content/decisions/0010-merge-authoring-apps-into-openedx-content.rst similarity index 96% rename from docs/decisions/0020-merge-authoring-apps-into-openedx-content.rst rename to docs/openedx_content/decisions/0010-merge-authoring-apps-into-openedx-content.rst index 0c352c5b3..ff71795d8 100644 --- a/docs/decisions/0020-merge-authoring-apps-into-openedx-content.rst +++ b/docs/openedx_content/decisions/0010-merge-authoring-apps-into-openedx-content.rst @@ -1,4 +1,6 @@ -20. Merge authoring apps into openedx_content (using Applets) +.. _openedx-content-adr-0010: + +10. Merge authoring apps into openedx_content (using Applets) ============================================================= Context @@ -50,7 +52,7 @@ We are going to take advantage of the fact that these two can be separated using There are a few high level constraints that we have to consider: -#. Existing openedx-platform migrations should not be modified. Existing openedx-platform migrations should remain unchanged. This is important to make sure that we do not introduce ordering inconsistencies for sites that have already run migrations for the old apps and are upgrading to a new release (e.g. Verawood). +#. Existing openedx-platform migrations should not be modified. This is important to make sure that we do not introduce ordering inconsistencies for sites that have already run migrations for the old apps and are upgrading to a new release (e.g. Verawood). #. The openedx-learning repo should not have any dependencies on openedx-platform migrations, because our dependencies strictly go in the other direction: openedx-platform calls openedx-learning, not the other way around. Furthermore, openedx-learning will often be run without openedx-platform, such as for local development or during CI. #. Two of the openedx-platform apps that have foreign keys to openedx-learning models are only in Studio's INSTALLED_APPS (``contentstore`` and ``modulestore_migrator``), while ``content_libraries`` is installed in both Studio and LMS. Migrations may be run for LMS or Studio first, depending on the user and environment. Tutor runs LMS first, but we can't assume that will always be true. #. We must support people who are installing from scratch, those who are upgrading from the Ulmo release, as well as those who are running off of the master branch of openedx-platform. @@ -66,7 +68,7 @@ Therefore, the migrations will happen in the following order: The tricky part is that all the ``opendx-learning`` migrations will run before any of the ``openedx-platform`` migrations run. We can't force it to do otherwise without making ``openedx-learning`` aware of ``opendx-platform``, and we explicitly want to avoid that. This makes things tricky with respect to the model state dependencies. There are two scenarios we have to worry about: -Migration from Scrach +Migration from Scratch The ``openedx-platform`` apps will each run the squashed migration that jumps straight to making foreign keys against the new ``openedx_content`` models, so the fact that the old authoring app models have been removed and the tables have been renamed doesn't matter. Migration from Ulmo/master diff --git a/docs/openedx_content/decisions/index.rst b/docs/openedx_content/decisions/index.rst new file mode 100644 index 000000000..b2b1b9f2f --- /dev/null +++ b/docs/openedx_content/decisions/index.rst @@ -0,0 +1,12 @@ +.. _openedx-content-decisions-index: + +Decisions +========= + +Architecture Decision Records for the ``openedx_content`` app. + +.. toctree:: + :maxdepth: 1 + :glob: + + * diff --git a/docs/openedx_content/index.rst b/docs/openedx_content/index.rst new file mode 100644 index 000000000..f68f625aa --- /dev/null +++ b/docs/openedx_content/index.rst @@ -0,0 +1,12 @@ +.. _openedx-content-index: + +openedx_content +=============== + +Django app for modeling and authoring course content structures. + +.. toctree:: + :maxdepth: 1 + + decisions/index + api_reference diff --git a/docs/public_apis/content_api.rst b/docs/openedx_content/public_apis/content_api.rst similarity index 81% rename from docs/public_apis/content_api.rst rename to docs/openedx_content/public_apis/content_api.rst index 926e2f9a8..937b80d81 100644 --- a/docs/public_apis/content_api.rst +++ b/docs/openedx_content/public_apis/content_api.rst @@ -1,3 +1,5 @@ +.. _openedx-content-api: + Content API =========== diff --git a/docs/public_apis/content_models.rst b/docs/openedx_content/public_apis/content_models.rst similarity index 79% rename from docs/public_apis/content_models.rst rename to docs/openedx_content/public_apis/content_models.rst index 81f3c2eb8..c005ffdac 100644 --- a/docs/public_apis/content_models.rst +++ b/docs/openedx_content/public_apis/content_models.rst @@ -1,3 +1,5 @@ +.. _openedx-content-models-api: + Content Models ============== diff --git a/docs/decisions/0001-purpose-of-this-repo.rst b/docs/openedx_core/decisions/0001-purpose-of-this-repo.rst similarity index 98% rename from docs/decisions/0001-purpose-of-this-repo.rst rename to docs/openedx_core/decisions/0001-purpose-of-this-repo.rst index 0b913886c..a857c181b 100644 --- a/docs/decisions/0001-purpose-of-this-repo.rst +++ b/docs/openedx_core/decisions/0001-purpose-of-this-repo.rst @@ -1,3 +1,5 @@ +.. _openedx-core-adr-0001: + 1. Purpose of this Repo ======================= diff --git a/docs/decisions/0021-openedx-core.rst b/docs/openedx_core/decisions/0002-openedx-core.rst similarity index 96% rename from docs/decisions/0021-openedx-core.rst rename to docs/openedx_core/decisions/0002-openedx-core.rst index f2741eeb2..0d738820c 100644 --- a/docs/decisions/0021-openedx-core.rst +++ b/docs/openedx_core/decisions/0002-openedx-core.rst @@ -1,4 +1,6 @@ -21. Learning Core is now Open edX Core +.. _openedx-core-adr-0002: + +2. Learning Core is now Open edX Core ====================================== Context @@ -47,8 +49,8 @@ We'll implement this change immediately as detailed in https://github.com/opened Rejected alternatives --------------------- -* Separate repos for ``openedx-content``, ``openedx-cbe``, etc. - +* Separate repos for ``openedx-content``, ``openedx-cbe``, etc. + * Axim is making a conscious effort to slow the proliferation of new repos, as it has been challenging to maintain consistent standards, tooling, and upgrades across all of them. If there is not a strong reason to separate repos, then we would prefer to start off with a single repo. * A combined top level Python package with nested apps: ``openedx_core.content.api``, ``openedx_core.cbe.api``, etc. diff --git a/docs/openedx_core/decisions/index.rst b/docs/openedx_core/decisions/index.rst new file mode 100644 index 000000000..c8caf79c7 --- /dev/null +++ b/docs/openedx_core/decisions/index.rst @@ -0,0 +1,12 @@ +.. _openedx-core-decisions-index: + +Decisions +========= + +Architecture Decision Records relating to the overall openedx-core repository. + +.. toctree:: + :maxdepth: 1 + :glob: + + * diff --git a/docs/getting_started.rst b/docs/openedx_core/getting_started.rst similarity index 92% rename from docs/getting_started.rst rename to docs/openedx_core/getting_started.rst index f203bbb50..7b5e0f0b5 100644 --- a/docs/getting_started.rst +++ b/docs/openedx_core/getting_started.rst @@ -1,3 +1,5 @@ +.. _openedx-core-getting-started: + Getting Started =============== diff --git a/docs/internationalization.rst b/docs/openedx_core/internationalization.rst similarity index 100% rename from docs/internationalization.rst rename to docs/openedx_core/internationalization.rst diff --git a/docs/testing.rst b/docs/openedx_core/testing.rst similarity index 100% rename from docs/testing.rst rename to docs/openedx_core/testing.rst diff --git a/docs/decisions/0022-competency-criteria-location.rst b/docs/openedx_learning/decisions/0001-competency-criteria-location.rst similarity index 79% rename from docs/decisions/0022-competency-criteria-location.rst rename to docs/openedx_learning/decisions/0001-competency-criteria-location.rst index 5c9670174..65a9e2177 100644 --- a/docs/decisions/0022-competency-criteria-location.rst +++ b/docs/openedx_learning/decisions/0001-competency-criteria-location.rst @@ -1,4 +1,6 @@ -22. Where in the codebase should CBE competency criteria go? +.. _openedx-learning-adr-0001: + +1. Where in the codebase should CBE competency criteria go? ============================================================ Context @@ -9,7 +11,7 @@ Decisions --------- CBE Competency Criteria, Student Competency Criteria Status, and Student Competency Status values should go in the openedx-learning repository as there are broader architectural goals to refactor as much code as possible out of the edx-platform repository into the openedx-learning repository such that it can be designed in a way that is easy for plugin developers to utilize. Additionally, we intend to treat CBE features as core features of Open edX rather than optional plugins, and as a result, CBE competency criteria and learner status should live in the learning core rather than in a separate new repo. -Given the current refactor of openedx-learning (see `0020-merge-authoring-apps-into-openedx-content.rst <0020-merge-authoring-apps-into-openedx-content.rst>`_), we will place CBE code inside the top-level ``openedx_learning`` app as an applet, alongside Learning Pathways. The intended layout is: +Given the current refactor of openedx-learning (see :ref:`openedx-content-adr-0010`), we will place CBE code inside the top-level ``openedx_learning`` app as an applet, alongside Learning Pathways. The intended layout is: :: @@ -27,53 +29,53 @@ This placement also keeps CBE close to shared learning-domain concepts that are Rejected Alternatives --------------------- -1. Put all CBE competency criteria and learner status in a single ``openedx_learning`` app under ``openedx_learning/apps/competency_criteria`` - - Pros: - - Keeps a single cohesive Django app for authoring criteria and storing learner status, reducing cross-app dependencies and simplifying migrations and APIs. - - Keeps Open edX-specific models (users, course identifiers, LMS/Studio workflows) out of the standalone ``openedx_tagging`` package and avoids forcing an authoring-only app to depend on learner runtime data. - - Cons: - - Does not align with the applet-based top-level structure being created in openedx-learning (``openedx_learning/applets/...``). -2. edx-platform repository - - Pros: This is where all data currently associated with students is stored, so it would match the existing pattern and reduce integration work for the LMS. - - Cons: The intention is to move core learning concepts out of edx-platform (see `0001-purpose-of-this-repo.rst <0001-purpose-of-this-repo.rst>`_), and keeping it there makes reuse and pluggability harder. -3. All code related to adding Competency Criteria to Open edX goes in openedx-learning/openedx\_learning/apps/authoring/competency\_criteria - - Pros: - - Tagging and competency criteria are part of content authoring workflows as is all of the other code in this directory. - - All other elements using the Publishable Framework are in this directory. - - Cons: - - We want each package of code to be independent, and this would separate competency criteria from the tags that they are dependent on. - - Competency criteria also includes learner status and runtime evaluation, which do not fit cleanly in the authoring app. - - The learner status models in this feature would have a ForeignKey to settings.AUTH_USER_MODEL, which is a runtime/learner concern. If those models lived under the authoring app, then the authoring app would have to import and depend on the user model, forcing an authoring-only package to carry learner/runtime dependencies. This may create unwanted coupling. -4. New Competency Criteria Content tables will go in openedx-learning/openedx_learning/openedx_tagging/core/competency_criteria. New Student Status tables will go in openedx-learning/student_status. - - Pros: - - Keeps competency criteria in the same package as the tags that they are dependent on. - - Cons: - - `openedx_tagging` is intended to be a standalone library without Open edX-specific dependencies (see `0007-tagging-app.rst <0007-tagging-app.rst>`_) competency criteria would violate that boundary. - - Splitting Competency Criteria and Student Statuses into two apps would require cross-app foreign keys (e.g., status rows pointing at criteria/tag rows in another app), migration ordering and dependency declarations to ensure tables exist in the right order, and shared business logic or APIs for computing/updating status that now must live in one app but reference models in the other. -5. Split competency criteria and learner statuses into two apps inside openedx-learning/openedx\_learning/apps (e.g., competency\_criteria and learner\_status) - - Pros: - - Clear separation between authoring configuration and computed learner state. - - Could allow different storage or scaling strategies for status data. - - Cons: - - Still introduces cross-app dependency and coordination for a single feature set. +1. Put all CBE competency criteria and learner status in a single ``openedx_learning`` app under ``openedx_learning/apps/competency_criteria`` + - Pros: + - Keeps a single cohesive Django app for authoring criteria and storing learner status, reducing cross-app dependencies and simplifying migrations and APIs. + - Keeps Open edX-specific models (users, course identifiers, LMS/Studio workflows) out of the standalone ``openedx_tagging`` package and avoids forcing an authoring-only app to depend on learner runtime data. + - Cons: + - Does not align with the applet-based top-level structure being created in openedx-learning (``openedx_learning/applets/...``). +2. edx-platform repository + - Pros: This is where all data currently associated with students is stored, so it would match the existing pattern and reduce integration work for the LMS. + - Cons: The intention is to move core learning concepts out of edx-platform (see :ref:`openedx-core-adr-0001`), and keeping it there makes reuse and pluggability harder. +3. All code related to adding Competency Criteria to Open edX goes in openedx-learning/openedx\_learning/apps/authoring/competency\_criteria + - Pros: + - Tagging and competency criteria are part of content authoring workflows as is all of the other code in this directory. + - All other elements using the Publishable Framework are in this directory. + - Cons: + - We want each package of code to be independent, and this would separate competency criteria from the tags that they are dependent on. + - Competency criteria also includes learner status and runtime evaluation, which do not fit cleanly in the authoring app. + - The learner status models in this feature would have a ForeignKey to settings.AUTH_USER_MODEL, which is a runtime/learner concern. If those models lived under the authoring app, then the authoring app would have to import and depend on the user model, forcing an authoring-only package to carry learner/runtime dependencies. This may create unwanted coupling. +4. New Competency Criteria Content tables will go in openedx-learning/openedx_learning/openedx_tagging/core/competency_criteria. New Student Status tables will go in openedx-learning/student_status. + - Pros: + - Keeps competency criteria in the same package as the tags that they are dependent on. + - Cons: + - `openedx_tagging` is intended to be a standalone library without Open edX-specific dependencies (see :ref:`openedx-tagging-adr-0002`) competency criteria would violate that boundary. + - Splitting Competency Criteria and Student Statuses into two apps would require cross-app foreign keys (e.g., status rows pointing at criteria/tag rows in another app), migration ordering and dependency declarations to ensure tables exist in the right order, and shared business logic or APIs for computing/updating status that now must live in one app but reference models in the other. +5. Split competency criteria and learner statuses into two apps inside openedx-learning/openedx\_learning/apps (e.g., competency\_criteria and learner\_status) + - Pros: + - Clear separation between authoring configuration and computed learner state. + - Could allow different storage or scaling strategies for status data. + - Cons: + - Still introduces cross-app dependency and coordination for a single feature set. - May be premature for the POC; adds overhead without proven need. -6. Store learner status in a separate service - - Pros: - - Scales independently and avoids write-heavy tables in the core app database. - - Could potentially reuse existing infrastructure for grades. - - Cons: - - Introduces eventual consistency and more integration complexity for LMS/Studio views. - - Requires additional infrastructure and operational ownership. -7. Split authoring and runtime into separate repos/packages - - Pros: - - Clear ownership boundaries and independent release cycles. - - Cons: - - Adds packaging and versioning overhead for a tightly coupled domain. +6. Store learner status in a separate service + - Pros: + - Scales independently and avoids write-heavy tables in the core app database. + - Could potentially reuse existing infrastructure for grades. + - Cons: + - Introduces eventual consistency and more integration complexity for LMS/Studio views. + - Requires additional infrastructure and operational ownership. +7. Split authoring and runtime into separate repos/packages + - Pros: + - Clear ownership boundaries and independent release cycles. + - Cons: + - Adds packaging and versioning overhead for a tightly coupled domain. - Increases coordination cost for migrations and API changes. -8. Migrate grading signals to openedx-events now and have openedx-learning consume events directly - - Pros: - - Aligns with the long-term direction of moving events out of edx-platform. - - Avoids a shim app in edx-platform and reduces tech debt. - - Cons: - - Requires cross-repo coordination and work beyond the current scope. +8. Migrate grading signals to openedx-events now and have openedx-learning consume events directly + - Pros: + - Aligns with the long-term direction of moving events out of edx-platform. + - Avoids a shim app in edx-platform and reduces tech debt. + - Cons: + - Requires cross-repo coordination and work beyond the current scope. - Depends on changes to openedx-events that are not yet scheduled or ready. diff --git a/docs/decisions/0023-competency-criteria-model.rst b/docs/openedx_learning/decisions/0002-competency-criteria-model.rst similarity index 99% rename from docs/decisions/0023-competency-criteria-model.rst rename to docs/openedx_learning/decisions/0002-competency-criteria-model.rst index 301b3e7f0..b41dca757 100644 --- a/docs/decisions/0023-competency-criteria-model.rst +++ b/docs/openedx_learning/decisions/0002-competency-criteria-model.rst @@ -1,4 +1,6 @@ -23. How should CBE competency achievement criteria be modeled in the database? +.. _openedx-learning-adr-0002: + +2. How should CBE competency achievement criteria be modeled in the database? ============================================================================== Context @@ -266,12 +268,12 @@ Rejected Alternatives 1. Update ``oel_tagging_taxonomy`` to have a new column for ``taxonomy_type`` where the value could be “Competency” or “Tag”. 1. Pros - + 1. Simpler model with fewer tables 2. Reuses existing taxonomy table and keeps reads straightforward when checking taxonomy usage 3. Avoids introducing an additional join for queries that only need to know whether a taxonomy is competency-enabled 2. Cons - + 1. Couples CBE concerns directly into the generic tagging domain model, reducing separation of concerns 2. Makes ``oel_tagging_taxonomy`` less generic and encourages enum/flag growth as new specialized usages are added 3. Prevents strong foreign key guarantees for CBE tables, since they can only point to ``oel_tagging_taxonomy`` and not specifically to competency-enabled taxonomies @@ -295,7 +297,7 @@ Rejected Alternatives 6. Performance risk if the objecttag table becomes very large and is queried for both generic tagging and competency criteria use cases with mostly-null criteria fields. 7. Future rule types may require different fields, further bloating ``objecttag`` and reducing performance for non-competency use cases. -3. Add a generic oel\_tagging\_objecttag\_metadata table to attempt to assist with pluggable metadata concept. This table would have foreign keys to each metadata table, currently only competency\_criteria\_group and competency\_criteria as well as a type field to indicate what metadata table is being pointed to. +3. Add a generic oel\_tagging\_objecttag\_metadata table to attempt to assist with pluggable metadata concept. This table would have foreign keys to each metadata table, currently only competency\_criteria\_group and competency\_criteria as well as a type field to indicate what metadata table is being pointed to. 1. Pros @@ -304,7 +306,7 @@ Rejected Alternatives 1. Adds additional overhead to retrieve specific metadata -4. Split rule storage into per-type tables (for example, ``competency_criteria_grade_rule`` and ``competency_criteria_mastery_rule``) instead of a single JSON payload. +4. Split rule storage into per-type tables (for example, ``competency_criteria_grade_rule`` and ``competency_criteria_mastery_rule``) instead of a single JSON payload. 1. Pros diff --git a/docs/decisions/0024-competency-criteria-versioning.rst b/docs/openedx_learning/decisions/0003-competency-criteria-versioning.rst similarity index 88% rename from docs/decisions/0024-competency-criteria-versioning.rst rename to docs/openedx_learning/decisions/0003-competency-criteria-versioning.rst index 47c89d593..60f4f5864 100644 --- a/docs/decisions/0024-competency-criteria-versioning.rst +++ b/docs/openedx_learning/decisions/0003-competency-criteria-versioning.rst @@ -1,11 +1,13 @@ -24. How should versioning be handled for CBE competency achievement criteria? +.. _openedx-learning-adr-0003: + +3. How should versioning be handled for CBE competency achievement criteria? ============================================================================= Context ------- -Course Authors and/or Platform Administrators will be entering the competency achievement criteria rules in Studio that learners are required to meet in order to demonstrate competencies. Depending on the institution, these Course Authors or Platform Administrators may have a variety of job titles, including Instructional Designer, Curriculum Designer, Instructor, LMS Administrator, Faculty, or other Staff. +Course Authors and/or Platform Administrators will be entering the competency achievement criteria rules in Studio that learners are required to meet in order to demonstrate competencies. Depending on the institution, these Course Authors or Platform Administrators may have a variety of job titles, including Instructional Designer, Curriculum Designer, Instructor, LMS Administrator, Faculty, or other Staff. -Typically, only one person would be responsible for entering competency achievement criteria rules in Studio for each course, though this person may change over time. However, entire programs could have many different Course Authors or Platform Administrators with this responsibility. +Typically, only one person would be responsible for entering competency achievement criteria rules in Studio for each course, though this person may change over time. However, entire programs could have many different Course Authors or Platform Administrators with this responsibility. Typically, institutions and instructional designers do not change the mastery requirements (competency achievement criteria) for their competencies frequently over time. However, the ability to do historical audit logging of changes within Studio can be a valuable feature to those who have mistakenly made changes and want to revert or those who want to experiment with new approaches. @@ -51,33 +53,33 @@ For the initial implementation, versioning and traceability of competency achiev Rejected Alternatives --------------------- -1. Defer competency achievement criteria versioning for the initial implementation. Store only the latest authored criteria and expose the latest published state in the LMS, consistent with current Studio/LMS behavior. - - Pros: +1. Defer competency achievement criteria versioning for the initial implementation. Store only the latest authored criteria and expose the latest published state in the LMS, consistent with current Studio/LMS behavior. + - Pros: - Keeps the initial implementation lightweight - Cons: - There is no built-in rollback or audit history - Adding versioning later will require data migration and careful choices about draft vs published defaults 2. Each model indicates version, status, and audit fields - - Pros: - - Simple and familiar pattern (version + status + created/updated metadata) - - Straightforward queries for the current published state - - Can support rollback by marking an earlier version as published - - Stable identifiers (original_ids) can anchor versions and ease potential future migrations - - Cons: - - Requires custom conventions for versioning across related tables and nested groups - - Lacks shared draft/publish APIs and immutable version objects that other authoring apps can reuse - - Not necessarily consistent with existing patterns in the codebase (though these are already not overly consistent). -3. Publishable framework in openedx-learning - - Pros: - - First-class draft/published semantics with immutable historical versions - - Consistent APIs and patterns shared across other authoring apps - - Cons: + - Pros: + - Simple and familiar pattern (version + status + created/updated metadata) + - Straightforward queries for the current published state + - Can support rollback by marking an earlier version as published + - Stable identifiers (original_ids) can anchor versions and ease potential future migrations + - Cons: + - Requires custom conventions for versioning across related tables and nested groups + - Lacks shared draft/publish APIs and immutable version objects that other authoring apps can reuse + - Not necessarily consistent with existing patterns in the codebase (though these are already not overly consistent). +3. Publishable framework in openedx-learning + - Pros: + - First-class draft/published semantics with immutable historical versions + - Consistent APIs and patterns shared across other authoring apps + - Cons: - Requires modeling criteria/groups as publishable entities and wiring Studio/LMS workflows to versioning APIs - Adds schema and migration complexity for a feature that does not yet require full versioning -4. Append-only audit log table (event history) - - Pros: - - Lightweight way to capture who changed what and when - - Enables basic rollback by replaying or reversing events - - Cons: - - Requires custom tooling to reconstruct past versions +4. Append-only audit log table (event history) + - Pros: + - Lightweight way to capture who changed what and when + - Enables basic rollback by replaying or reversing events + - Cons: + - Requires custom tooling to reconstruct past versions - Does not align with existing publishable versioning patterns diff --git a/docs/decisions/images/CompetencyCriteriaModel.png b/docs/openedx_learning/decisions/images/CompetencyCriteriaModel.png similarity index 100% rename from docs/decisions/images/CompetencyCriteriaModel.png rename to docs/openedx_learning/decisions/images/CompetencyCriteriaModel.png diff --git a/docs/openedx_learning/decisions/index.rst b/docs/openedx_learning/decisions/index.rst new file mode 100644 index 000000000..1744c4093 --- /dev/null +++ b/docs/openedx_learning/decisions/index.rst @@ -0,0 +1,12 @@ +.. _openedx-learning-decisions-index: + +Decisions +========= + +Architecture Decision Records for the ``openedx_learning`` app. + +.. toctree:: + :maxdepth: 1 + :glob: + + * diff --git a/docs/openedx_learning/index.rst b/docs/openedx_learning/index.rst new file mode 100644 index 000000000..b8d08d8c4 --- /dev/null +++ b/docs/openedx_learning/index.rst @@ -0,0 +1,11 @@ +.. _openedx-learning-index: + +openedx_learning +================ + +Django app for learner-facing models including competency-based education. + +.. toctree:: + :maxdepth: 1 + + decisions/index diff --git a/docs/decisions/0004-content-tagging.rst b/docs/openedx_tagging/decisions/0001-content-tagging.rst similarity index 98% rename from docs/decisions/0004-content-tagging.rst rename to docs/openedx_tagging/decisions/0001-content-tagging.rst index 0f43fd4eb..94bb677e7 100644 --- a/docs/decisions/0004-content-tagging.rst +++ b/docs/openedx_tagging/decisions/0001-content-tagging.rst @@ -1,4 +1,6 @@ -4. Content Tagging +.. _openedx-tagging-adr-0001: + +1. Content Tagging ================== Context diff --git a/docs/decisions/0007-tagging-app.rst b/docs/openedx_tagging/decisions/0002-tagging-app.rst similarity index 97% rename from docs/decisions/0007-tagging-app.rst rename to docs/openedx_tagging/decisions/0002-tagging-app.rst index 82ee9ecb1..9f9bcd773 100644 --- a/docs/decisions/0007-tagging-app.rst +++ b/docs/openedx_tagging/decisions/0002-tagging-app.rst @@ -1,4 +1,6 @@ -7. Tagging App structure +.. _openedx-tagging-adr-0002: + +2. Tagging App structure ======================== Status diff --git a/docs/decisions/0008-tagging-tree-data-arch.rst b/docs/openedx_tagging/decisions/0003-tagging-tree-data-arch.rst similarity index 97% rename from docs/decisions/0008-tagging-tree-data-arch.rst rename to docs/openedx_tagging/decisions/0003-tagging-tree-data-arch.rst index eaf2d0633..a48dcf84b 100644 --- a/docs/decisions/0008-tagging-tree-data-arch.rst +++ b/docs/openedx_tagging/decisions/0003-tagging-tree-data-arch.rst @@ -1,4 +1,6 @@ -8. Tag tree data structure +.. _openedx-tagging-adr-0003: + +3. Tag tree data structure ========================== Context diff --git a/docs/decisions/0009-tagging-administrators.rst b/docs/openedx_tagging/decisions/0004-tagging-administrators.rst similarity index 97% rename from docs/decisions/0009-tagging-administrators.rst rename to docs/openedx_tagging/decisions/0004-tagging-administrators.rst index 255b3f1e0..8694076a6 100644 --- a/docs/decisions/0009-tagging-administrators.rst +++ b/docs/openedx_tagging/decisions/0004-tagging-administrators.rst @@ -1,4 +1,6 @@ -9. Taxonomy administrators +.. _openedx-tagging-adr-0004: + +4. Taxonomy administrators ========================== Context diff --git a/docs/decisions/0010-taxonomy-enable-context.rst b/docs/openedx_tagging/decisions/0005-taxonomy-enable-context.rst similarity index 98% rename from docs/decisions/0010-taxonomy-enable-context.rst rename to docs/openedx_tagging/decisions/0005-taxonomy-enable-context.rst index d81233aaa..c56852f2c 100644 --- a/docs/decisions/0010-taxonomy-enable-context.rst +++ b/docs/openedx_tagging/decisions/0005-taxonomy-enable-context.rst @@ -1,4 +1,6 @@ -10. Taxonomy enabled for context +.. _openedx-tagging-adr-0005: + +5. Taxonomy enabled for context ================================ Status diff --git a/docs/decisions/0011-tag-changes.rst b/docs/openedx_tagging/decisions/0006-tag-changes.rst similarity index 97% rename from docs/decisions/0011-tag-changes.rst rename to docs/openedx_tagging/decisions/0006-tag-changes.rst index 6628135b9..e5b64d252 100644 --- a/docs/decisions/0011-tag-changes.rst +++ b/docs/openedx_tagging/decisions/0006-tag-changes.rst @@ -1,4 +1,6 @@ -11. Taxonomy and tag changes +.. _openedx-tagging-adr-0006: + +6. Taxonomy and tag changes ============================ Context diff --git a/docs/decisions/0012-system-taxonomy-creation.rst b/docs/openedx_tagging/decisions/0007-system-taxonomy-creation.rst similarity index 97% rename from docs/decisions/0012-system-taxonomy-creation.rst rename to docs/openedx_tagging/decisions/0007-system-taxonomy-creation.rst index 36c27dcde..8a886d76b 100644 --- a/docs/decisions/0012-system-taxonomy-creation.rst +++ b/docs/openedx_tagging/decisions/0007-system-taxonomy-creation.rst @@ -1,4 +1,6 @@ -12. System-defined Taxonomy & Tags creation +.. _openedx-tagging-adr-0007: + +7. System-defined Taxonomy & Tags creation ============================================ Context diff --git a/docs/decisions/0013-system-taxonomy-auto-tagging.rst b/docs/openedx_tagging/decisions/0008-system-taxonomy-auto-tagging.rst similarity index 97% rename from docs/decisions/0013-system-taxonomy-auto-tagging.rst rename to docs/openedx_tagging/decisions/0008-system-taxonomy-auto-tagging.rst index ef506aaf2..4b19e292f 100644 --- a/docs/decisions/0013-system-taxonomy-auto-tagging.rst +++ b/docs/openedx_tagging/decisions/0008-system-taxonomy-auto-tagging.rst @@ -1,4 +1,6 @@ -13. System-defined automatic tagging +.. _openedx-tagging-adr-0008: + +8. System-defined automatic tagging ===================================== Context diff --git a/docs/decisions/0014-single-taxonomy-view-api.rst b/docs/openedx_tagging/decisions/0009-single-taxonomy-view-api.rst similarity index 99% rename from docs/decisions/0014-single-taxonomy-view-api.rst rename to docs/openedx_tagging/decisions/0009-single-taxonomy-view-api.rst index 70a528df8..43710f8da 100644 --- a/docs/decisions/0014-single-taxonomy-view-api.rst +++ b/docs/openedx_tagging/decisions/0009-single-taxonomy-view-api.rst @@ -1,4 +1,6 @@ -14. Single taxonomy view API +.. _openedx-tagging-adr-0009: + +9. Single taxonomy view API ===================================== Status diff --git a/docs/openedx_tagging/decisions/index.rst b/docs/openedx_tagging/decisions/index.rst new file mode 100644 index 000000000..d4eddca60 --- /dev/null +++ b/docs/openedx_tagging/decisions/index.rst @@ -0,0 +1,12 @@ +.. _openedx-tagging-decisions-index: + +Decisions +========= + +Architecture Decision Records for the ``openedx_tagging`` app. + +.. toctree:: + :maxdepth: 1 + :glob: + + * diff --git a/docs/openedx_tagging/index.rst b/docs/openedx_tagging/index.rst new file mode 100644 index 000000000..ee58a075f --- /dev/null +++ b/docs/openedx_tagging/index.rst @@ -0,0 +1,11 @@ +.. _openedx-tagging-index: + +openedx_tagging +=============== + +Standalone Django app for tagging content with taxonomies. + +.. toctree:: + :maxdepth: 1 + + decisions/index diff --git a/docs/readme.rst b/docs/readme.rst deleted file mode 100644 index 72a335581..000000000 --- a/docs/readme.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../README.rst diff --git a/setup.py b/setup.py index 94e328c82..ea3e2478d 100755 --- a/setup.py +++ b/setup.py @@ -76,7 +76,7 @@ def is_requirement(line): include_package_data=True, install_requires=load_requirements('requirements/base.in'), python_requires=">=3.12", - license="AGPL 3.0", + license="AGPL-3.0-only", zip_safe=False, keywords='Python edx', classifiers=[ @@ -84,7 +84,6 @@ def is_requirement(line): 'Framework :: Django', 'Framework :: Django :: 5.2', 'Intended Audience :: Developers', - 'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)', 'Natural Language :: English', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.12', diff --git a/src/openedx_content/backcompat/readme.rst b/src/openedx_content/backcompat/readme.rst index 1f844641e..00bc0511c 100644 --- a/src/openedx_content/backcompat/readme.rst +++ b/src/openedx_content/backcompat/readme.rst @@ -1,6 +1,6 @@ Backwards Compatibility App Package =================================== -The apps in this package should not be modified. They are a byproduct of our migration from having a bunch of little authoring apps to having one unified app. They exist to provide backwards compatibilty for database migrations (see `<0020-authoring-as-one-app.rst>`_). +The apps in this package should not be modified. They are a byproduct of our migration from having a bunch of little authoring apps to having one unified app. They exist to provide backwards compatibilty for database migrations (see :ref:`openedx-content-adr-0010`_). At some point in the future, we will remove this package and modify the initial migration for the ``authoring`` app to actually create the models for real, instead of using ``SeparateDatabaseAndState`` to fake the database side of the migration. For anyone who has already run the ``openedx_content`` migrations, the modified initial migration won't run anyway. Anyone setting things up for the first time would get the ``openedx_content`` models created without the intermediate steps of creating all the smaller app models first and renaming them. We should not do this before the Willow release, but there's no real downside to doing it later. diff --git a/src/openedx_content/settings_api.py b/src/openedx_content/settings_api.py index cf6d890da..dce99b4fb 100644 --- a/src/openedx_content/settings_api.py +++ b/src/openedx_content/settings_api.py @@ -14,7 +14,7 @@ def openedx_content_backcompat_apps_to_install(): from many Django apps within `openedx_learning.apps.authoring` into a single `openedx_content` Django app. But, anything installing the `openedx_content` Django will also need to install these backcompat Django apps for the forseeable future. For more details, see - /docs/decisions/0020-merge-authoring-apps-into-openedx-content.rst + /docs/openedx_content/decisions/0010-merge-authoring-apps-into-openedx-content.rst Example::