feat: add reconnect_legacy_discussion_threads management command - #656
Merged
ahmed-arb merged 2 commits intoJul 1, 2026
Merged
Conversation
Courses authored with legacy inline discussion XBlocks store their threads in the forum under the XBlock's discussion_id (the commentable_id). Switching a course to the openedx in-context provider mints fresh uuid4 topic external ids that never reuse the legacy discussion_id, so existing threads point at commentable ids no DiscussionTopicLink references: they vanish from units, from the Discussions MFE Topics list, and their counts read zero. Graded units get no topic link at all unless enable_graded_units is set. There is no upstream remediation for this; upstream's own migration deletes and recreates topic links with new UUIDs and does not reconnect existing threads. This command points each unit's topic external_id back at the legacy discussion_id (swapping an existing link or creating one for graded units and flipping enable_graded_units), routes anything that cannot map 1:1 to a unit to a course-level topic, and recomputes per-course user stats so the Learners tab populates. It performs only Django-model writes plus the stats recompute, so it is reversible, and defaults to a dry-run. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Mongo->MySQL forum migration brings threads but not ForumUser records, and the forum's per-course stats read does ForumUser.objects.get() per stat-bearing user, so a single missing record makes the Learners endpoint fail with ForumUser.DoesNotExist. update_course_users_stats alone therefore left the Learners tab broken. Seed ForumUser for the course's enrolled users before recomputing stats so the read path has every record it needs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Courses authored with legacy inline discussion XBlocks store their threads in the forum keyed by the XBlock's
discussion_id(thecommentable_id). When such a course is switched to theopenedxin-context provider,DiscussionTopicLinkrows are created with freshly generateduuid4()external ids that never reuse the legacydiscussion_id, so the existing threads point at commentable ids that no topic references. The result is that old discussions disappear from their units, the Discussions MFE "Topics" list and counts read empty, and the "Learners" tab is empty because the forum-v2 per-course user stats were never recomputed. Graded units make it worse: they get no topic link at all unlessenable_graded_unitsis set. There is no upstream remediation for this — upstream's own migration deletes and recreates topic links with new UUIDs, so it does not reconnect existing threads.This command repairs affected courses. For every commentable that has threads but is not referenced by any topic link, it points the parent unit's topic
external_idback at the legacydiscussion_id— swapping an existing link, or creating an enabled one for graded units and flippingenable_graded_units=Trueon the course config so the link survives re-publish. Anything that cannot be mapped one-to-one to a unit (a unit with two posted-in XBlocks, or a commentable whose XBlock no longer exists) is registered as a course-level topic and reported rather than overwritten. It then recomputes per-course user stats so the Learners tab populates. Only Django-model writes (DiscussionsConfiguration/DiscussionTopicLink) plus the stats recompute are performed — no modulestore or forum-store writes — so the change is reversible. It defaults to a dry-run; pass--applyto write and--reindexto rebuild the forum search index once at the end.Run it per course or across every
openedx-provider course:🤖 Generated with Claude Code