Skip to content

feat: add management command for one-time cleanup of retired users - #448

Merged
ktyagiapphelix2u merged 1 commit into
release-ulmofrom
ktyagi/migrations
Aug 31, 2026
Merged

feat: add management command for one-time cleanup of retired users#448
ktyagiapphelix2u merged 1 commit into
release-ulmofrom
ktyagi/migrations

Conversation

@ktyagiapphelix2u

Copy link
Copy Markdown

Summary

Adds a one-time management command, cleanup_retired_manual_verifications, to clear PII and delete ManualVerification records for retired users. The command supports a --dry-run mode and only executes when REDACT_MANUAL_VERIFICATION_HISTORICAL_PII is enabled.

Jira Private Ticket

https://2u-internal.atlassian.net/browse/BOMS-708

Copilot AI lite review requested due to automatic review settings August 31, 2026 09:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a one-time Django management command in verify_student to remove ManualVerification PII and delete ManualVerification rows for users who have been retired, along with a small test suite to validate the behavior.

Changes:

  • Introduces cleanup_retired_manual_verifications management command with a --dry-run mode and a feature gate.
  • Adds tests covering the command’s skip behavior when the redaction toggle is disabled and basic delete behavior for a retired user.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
lms/djangoapps/verify_student/management/commands/cleanup_retired_manual_verifications.py New management command to redact/delete ManualVerification rows for retired users, with dry-run and toggle gating.
lms/djangoapps/verify_student/management/commands/tests/test_cleanup_retired_manual_verifications.py New tests for the management command’s behavior.
Suppressed comments (1)

lms/djangoapps/verify_student/management/commands/cleanup_retired_manual_verifications.py:39

  • After switching to the REDACT_MANUAL_VERIFICATION_HISTORICAL_PII SettingToggle (as used elsewhere in verify_student), the guard should call .is_enabled() rather than reading from django.conf.settings; this also avoids a runtime error if settings is no longer imported.
    def handle(self, *args, **options):
        if not getattr(settings, 'REDACT_MANUAL_VERIFICATION_HISTORICAL_PII', False):
            log.warning('Skipping. REDACT_MANUAL_VERIFICATION_HISTORICAL_PII must first be enabled.')
            return

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +43 to +45
retired_records = ManualVerification.objects.filter(
user__userretirementrequest__isnull=False,
)
Comment on lines +11 to +13
from common.djangoapps.student.tests.factories import UserFactory
from lms.djangoapps.verify_student.models import ManualVerification
from openedx.core.djangoapps.user_api.tests.factories import UserRetirementRequestFactory
Comment on lines +46 to +69
def test_redacts_and_deletes_retired_records(self):
"""
Test that the command redacts and deletes retired users' records but leaves active users untouched.
"""
retired_user = UserFactory.create()
active_user = UserFactory.create()

ManualVerification.objects.create(
user=retired_user,
name='Retired User Name',
status='approved',
)
ManualVerification.objects.create(
user=active_user,
name='Active User Name',
status='approved',
)
UserRetirementRequestFactory(user=retired_user)

with override_settings(REDACT_MANUAL_VERIFICATION_HISTORICAL_PII=True):
call_command('cleanup_retired_manual_verifications')

assert not ManualVerification.objects.filter(user=retired_user).exists()
assert ManualVerification.objects.filter(user=active_user, name='Active User Name').exists()
Comment on lines +7 to +11
from django.conf import settings
from django.core.management.base import BaseCommand

from lms.djangoapps.verify_student.models import ManualVerification

Comment on lines +58 to +63
try:
retired_records.update(name='')
retired_records.delete()
except Exception as exc:
log.exception('Failed to redact/delete ManualVerification records: %s', exc)
raise
@ktyagiapphelix2u
ktyagiapphelix2u merged commit c62ca51 into release-ulmo Aug 31, 2026
65 checks passed
@ktyagiapphelix2u
ktyagiapphelix2u deleted the ktyagi/migrations branch August 31, 2026 09:29
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.

3 participants