Skip to content

feat: Add transcript editor toggle and update related serializers and tests#267

Merged
abhalsod-sonata merged 1 commit into
release-ulmofrom
feat/TNL2-608
May 13, 2026
Merged

feat: Add transcript editor toggle and update related serializers and tests#267
abhalsod-sonata merged 1 commit into
release-ulmofrom
feat/TNL2-608

Conversation

@abhalsod-sonata
Copy link
Copy Markdown

@abhalsod-sonata abhalsod-sonata commented May 5, 2026

Description

This PR adds support for a new in-platform transcript editor feature in Studio's videos page through a new waffle flag contentstore.enable_transcript_editor. When enabled, course staff will be able to open an editor modal from the transcript row action menu and edit transcript cue text directly in the browser, with edits saved via a new PATCH API endpoint.

Key Changes:

  • Added new TRANSCRIPT_EDITOR waffle flag (default: False) to cms/djangoapps/contentstore/toggles.py
  • Exposed the waffle flag status in the course waffle flags REST API serializer
  • Updated transcript upload handler to correctly differentiate between creating new transcripts (201) and replacing existing ones (200)
  • Added comprehensive test coverage for the new waffle flag with global and per-course override scenarios

User Impact:

  • Course Authors: When the flag is enabled for their course, they'll see an "Edit transcript" option in the videos page and can edit transcripts directly in the browser instead of uploading files
  • Developers: New transcript editor endpoint and waffle flag infrastructure for building out the full editor UI
  • Operators: Can control rollout of the feature via waffle flags at both global and per-course levels

The existing upload, download, and delete transcript flows remain unaffected.


Supporting information


Testing instructions

Setup

make dev.provision
make dev.up
cd cms

Test 1: Verify waffle flag defaults to False

python manage.py shell
>>> from cms.djangoapps.contentstore import toggles
>>> from opaque_keys.edx.keys import CourseKey
>>> course_key = CourseKey.from_string("course-v1:edX+DemoX+Demo_Course")
>>> toggles.transcript_editor_enabled(course_key)
False

Test 2: Enable flag globally and verify

  1. In Django admin: Waffle Flags > Flags > create new one > contentstore.enable_transcript_editor`
  2. Test in shell:
    >>> toggles.transcript_editor_enabled(course_key)
    True
  3. Hit the waffle flags API endpoint:
    curl -X GET "http://localhost:8000/api/courses/v1/course_waffle_flags/"
    Verify "transcript_editor": true in response

Test 3: Test per-course override

python manage.py shell
>>> from cms.djangoapps.contentstore.models import CourseWaffleFlagOverrideModel
>>> from cms.djangoapps.contentstore import toggles
>>> from opaque_keys.edx.keys import CourseKey
>>> course_key = CourseKey.from_string("course-v1:edX+DemoX+Demo_Course")
>>> # Create override to enable for specific course
>>> override = CourseWaffleFlagOverrideModel.objects.create(
...     waffle_flag=toggles.TRANSCRIPT_EDITOR.name,
...     course_id=course_key,
...     enabled=True,
... )
>>> toggles.transcript_editor_enabled(course_key)
True

Test 4: Verify transcript upload returns correct status codes

  • New transcript upload: Should return 201 (Created)
  • Replacing existing transcript: Should return 200 (OK)

Test via API:

# First upload - should return 201
curl -X POST "http://localhost:8000/transcripts/upload" \
  -F "video_id=abc123" \
  -F "new_language_code=en" \
  -F "file=@transcript.srt"

# Second upload of same language - should return 200
curl -X POST "http://localhost:8000/transcripts/upload" \
  -F "video_id=abc123" \
  -F "new_language_code=en" \
  -F "file=@transcript_updated.srt"

Run Tests

# Run waffle flag tests
pytest cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_waffle_flags.py -v

# Run transcript storage tests
pytest cms/djangoapps/contentstore/tests/test_transcript_storage_handlers.py -v

Other information

Backwards Compatibility

  • Feature flag defaults to False, so existing behavior is unchanged
  • Transcript upload/download/delete endpoints are unaffected
  • API response format is backwards compatible (only adds new field when serializer is used)

Database Changes

  • No database migrations required
  • Uses existing WaffleFlagCourseOverrideModel for per-course overrides

Security

  • No new authentication requirements
  • Transcript editor endpoint will use existing course access controls (requires course staff permissions)
  • Waffle flag check provides additional layer of control for feature rollout

Accessibility

  • No new UI in this PR; feature flag infrastructure only
  • When editor modal is built, it must follow WCAG 2.1 AA standards

Special Concerns

  • The transcript editor modal UI implementation will be in a follow-up PR
  • Transcript upload status code change (200 vs 201) is important for frontend clients to properly differentiate new vs. updated transcripts
  • This flag can be safely enabled/disabled in production without breaking existing functionality

Dependencies

  • No external dependencies
  • Standalone PR that can be merged independently
  • Blocks: Transcript editor modal UI PR

Summary for Reviewers

This PR provides the foundational waffle flag infrastructure and API adjustments needed for the transcript editor feature. The main changes are:

  1. New waffle flag with proper documentation (OEP-21)
  2. API integration of the flag in course waffle flags serializer
  3. Improved transcript upload handler status code logic (201 for creation, 200 for updates)
  4. Comprehensive test coverage including global and per-course flag scenarios

The feature flag defaults to False, so there's zero impact on existing functionality until explicitly enabled.


Files Changed Summary

File Change
cms/djangoapps/contentstore/toggles.py Added TRANSCRIPT_EDITOR waffle flag and transcript_editor_enabled() helper
cms/djangoapps/contentstore/rest_api/v1/serializers/course_waffle_flags.py Added transcript_editor field to CourseWaffleFlagsSerializer
cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_waffle_flags.py Added 3 test cases for transcript_editor flag (default, global, per-course)
cms/djangoapps/contentstore/transcript_storage_handlers.py Updated upload_transcript() to return 200 for replacements, 201 for new uploads

@abhalsod-sonata abhalsod-sonata merged commit 564ac66 into release-ulmo May 13, 2026
64 checks passed
@abhalsod-sonata abhalsod-sonata deleted the feat/TNL2-608 branch May 13, 2026 14:28
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.

2 participants