From 1f0f46b8aef84503cfec83181081171f314b5f26 Mon Sep 17 00:00:00 2001 From: ktyagiapphelix2u Date: Fri, 24 Jul 2026 06:07:29 +0000 Subject: [PATCH 1/2] chore: redact and delete retired manual verification records via data migration --- ...0017_cleanup_retired_manualverification.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 lms/djangoapps/verify_student/migrations/0017_cleanup_retired_manualverification.py diff --git a/lms/djangoapps/verify_student/migrations/0017_cleanup_retired_manualverification.py b/lms/djangoapps/verify_student/migrations/0017_cleanup_retired_manualverification.py new file mode 100644 index 000000000000..8dc26a0d20ee --- /dev/null +++ b/lms/djangoapps/verify_student/migrations/0017_cleanup_retired_manualverification.py @@ -0,0 +1,38 @@ +# Generated by Django 5.2.15 on 2026-07-24 06:03 + +from django.db import migrations +from django.db.models import Q + + +def cleanup_retired_manual_verifications(apps, schema_editor): + """Clear PII, then delete matching retired-user manual verification rows.""" + db_alias = schema_editor.connection.alias + ManualVerification = apps.get_model('verify_student', 'ManualVerification') + + retired_user_filter = ( + Q(user__username__startswith='retired__user_') | + ( + Q(user__email__startswith='retired__user_') & + Q(user__email__endswith='@retired.invalid') + ) + ) + + retired_records = ManualVerification.objects.using(db_alias).filter(retired_user_filter) + + # Clear PII, then delete matching records. + retired_records.update(name='') + retired_records.delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ("verify_student", "0016_remove_verificationattempt_created_and_more"), + ] + + operations = [ + migrations.RunPython( + cleanup_retired_manual_verifications, + reverse_code=migrations.RunPython.noop, + ), + ] From 7f03c877b14baff4c70ba0ef21109eb6115a69e9 Mon Sep 17 00:00:00 2001 From: ktyagiapphelix2u Date: Mon, 27 Jul 2026 09:39:18 +0000 Subject: [PATCH 2/2] chore: redact and delete retired manual verification records via data migration --- ...0017_cleanup_retired_manualverification.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lms/djangoapps/verify_student/migrations/0017_cleanup_retired_manualverification.py b/lms/djangoapps/verify_student/migrations/0017_cleanup_retired_manualverification.py index 8dc26a0d20ee..63512e62cdc5 100644 --- a/lms/djangoapps/verify_student/migrations/0017_cleanup_retired_manualverification.py +++ b/lms/djangoapps/verify_student/migrations/0017_cleanup_retired_manualverification.py @@ -1,25 +1,24 @@ # Generated by Django 5.2.15 on 2026-07-24 06:03 +from django.conf import settings from django.db import migrations -from django.db.models import Q def cleanup_retired_manual_verifications(apps, schema_editor): - """Clear PII, then delete matching retired-user manual verification rows.""" + """ + Clear PII, then delete manual verification rows for retired users. + """ + if not getattr(settings, "REDACT_MANUAL_VERIFICATION_HISTORICAL_PII", False): + return + db_alias = schema_editor.connection.alias ManualVerification = apps.get_model('verify_student', 'ManualVerification') - retired_user_filter = ( - Q(user__username__startswith='retired__user_') | - ( - Q(user__email__startswith='retired__user_') & - Q(user__email__endswith='@retired.invalid') - ) + retired_records = ManualVerification.objects.using(db_alias).filter( + user__userretirementrequest__isnull=False, ) - retired_records = ManualVerification.objects.using(db_alias).filter(retired_user_filter) - - # Clear PII, then delete matching records. + # Clear PII, then delete matching records to take care of any soft delete setup in downstream systems. retired_records.update(name='') retired_records.delete() @@ -28,6 +27,7 @@ class Migration(migrations.Migration): dependencies = [ ("verify_student", "0016_remove_verificationattempt_created_and_more"), + ("user_api", "0003_userretirementrequest"), ] operations = [