Skip to content

feat: add reconnect_legacy_discussion_threads management command - #656

Merged
ahmed-arb merged 2 commits into
develop-teakfrom
ahmed-arb/reconnect-legacy-discussion-threads
Jul 1, 2026
Merged

feat: add reconnect_legacy_discussion_threads management command#656
ahmed-arb merged 2 commits into
develop-teakfrom
ahmed-arb/reconnect-legacy-discussion-threads

Conversation

@ahmed-arb

Copy link
Copy Markdown
Collaborator

Courses authored with legacy inline discussion XBlocks store their threads in the forum keyed by the XBlock's discussion_id (the commentable_id). When such a course is switched to the openedx in-context provider, DiscussionTopicLink rows are created with freshly generated uuid4() external ids that never reuse the legacy discussion_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 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, 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_id back at the legacy discussion_id — swapping an existing link, or creating an enabled one for graded units and flipping enable_graded_units=True on 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 --apply to write and --reindex to rebuild the forum search index once at the end.

Run it per course or across every openedx-provider course:

./manage.py lms reconnect_legacy_discussion_threads course-v1:ORG+NUM+RUN
./manage.py lms reconnect_legacy_discussion_threads all --apply --reindex

🤖 Generated with Claude Code

ahmed-arb and others added 2 commits June 30, 2026 17:54
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>
@ahmed-arb
ahmed-arb merged commit 4557606 into develop-teak Jul 1, 2026
10 of 11 checks passed
@ahmed-arb
ahmed-arb deleted the ahmed-arb/reconnect-legacy-discussion-threads branch July 3, 2026 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant