-
Notifications
You must be signed in to change notification settings - Fork 356
[ENG-9854][ENG-10025][ENG-10040][ENG-10095] NR Post-release model migration + model dependent bug-fixes #11540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
cslzchen
merged 11 commits into
CenterForOpenScience:feature/notifications-refactor-post-release
from
Ostap-Zherebetskyi:hotfix/NR_model_migration
Jan 28, 2026
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
f0b7056
Add fake_sent field to Notification model and update notification cre…
Ostap-Zherebetskyi ce14838
add unique_together constraint
Ostap-Zherebetskyi 0e3f9bc
Add 'PARTIAL_SUCCESS' status to EmailTask model and update email task…
Ostap-Zherebetskyi e90bb1c
NR migration [ENG-10040, ENG-10025, ENG-9854]
Ostap-Zherebetskyi 08e1ea2
Remove subscription if notifications.tasks.send_moderator_email_task …
Ostap-Zherebetskyi ab06f57
Apply suggestion from @Ostap-Zherebetskyi remove datetime
Ostap-Zherebetskyi c0f944f
Add 'no_login_email_last_sent' field to OSFUser and update email task…
Ostap-Zherebetskyi cd80036
Rename migration name for NR post-release
cslzchen 6bc138c
Improve unit test: test_emit_frequency_none
cslzchen 09a570d
Remove `seen` from `Notification` and re-make migrations
cslzchen c5fa8bc
`mark_sent()` now handles `fake_sent=True`, and only `save()` once
cslzchen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Generated by Django 4.2.17 on 2026-01-27 21:03 | ||
|
|
||
| from django.db import migrations, models | ||
| import osf.utils.fields | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ('contenttypes', '0002_remove_content_type_name'), | ||
| ('osf', '0035_merge_20251215_1451'), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.RemoveField( | ||
| model_name='notification', | ||
| name='seen', | ||
| ), | ||
| migrations.AddField( | ||
| model_name='notification', | ||
| name='fake_sent', | ||
| field=models.BooleanField(default=False), | ||
| ), | ||
| migrations.AddField( | ||
| model_name='osfuser', | ||
| name='no_login_email_last_sent', | ||
| field=osf.utils.fields.NonNaiveDateTimeField(blank=True, null=True), | ||
| ), | ||
| migrations.AlterField( | ||
| model_name='emailtask', | ||
| name='status', | ||
| field=models.CharField(choices=[('PENDING', 'Pending'), ('NO_USER_FOUND', 'No User Found'), ('USER_DISABLED', 'User Disabled'), ('STARTED', 'Started'), ('SUCCESS', 'Success'), ('FAILURE', 'Failure'), ('RETRY', 'Retry'), ('PARTIAL_SUCCESS', 'Partial Success'), ('AUTO_FIXED', 'Auto Fixed')], default='PENDING', max_length=20), | ||
| ), | ||
| migrations.AlterUniqueTogether( | ||
| name='notificationsubscription', | ||
| unique_together={('notification_type', 'user', 'content_type', 'object_id', '_is_digest')}, | ||
| ), | ||
| ] |
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
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -60,31 +60,29 @@ def find_inactive_users_without_enqueued_or_sent_no_login(): | |
| Match your original inactivity rules, but exclude users who already have a no_login EmailTask | ||
| either pending, started, retrying, or already sent successfully. | ||
| """ | ||
| now = timezone.now() | ||
cslzchen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Subquery: Is there already a not-yet-failed/aborted EmailTask for this user with our prefix? | ||
| existing_no_login = EmailTask.objects.filter( | ||
| user_id=OuterRef('pk'), | ||
| task_id__startswith=NO_LOGIN_PREFIX, | ||
| status__in=['PENDING', 'STARTED', 'RETRY', 'SUCCESS'], | ||
| ) | ||
| cutoff_query = Q(date_last_login__gte=settings.NO_LOGIN_EMAIL_CUTOFF - settings.NO_LOGIN_WAIT_TIME) if settings.NO_LOGIN_EMAIL_CUTOFF else Q() | ||
| base_q = OSFUser.objects.filter( | ||
| cutoff_query, | ||
| is_active=True, | ||
| ).filter( | ||
| Q( | ||
| date_last_login__lt=timezone.now() - settings.NO_LOGIN_WAIT_TIME, | ||
| date_last_login__lt=now - settings.NO_LOGIN_WAIT_TIME, | ||
| # NOT tagged osf4m | ||
| ) & ~Q(tags__name='osf4m') | ||
| | | ||
| Q( | ||
| date_last_login__lt=timezone.now() - settings.NO_LOGIN_OSF4M_WAIT_TIME, | ||
| date_last_login__lt=now - settings.NO_LOGIN_OSF4M_WAIT_TIME, | ||
| tags__name='osf4m' | ||
| ) | ||
| ).distinct() | ||
|
|
||
| # Exclude users who already have a task for this email type | ||
| return base_q.annotate(_has_task=Exists(existing_no_login)).filter(_has_task=False) | ||
| # Exclude users who have already received a no-login email recently | ||
| return base_q.filter( | ||
| Q(no_login_email_last_sent__isnull=True) | | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the new check only checks the user field, we need a script to migrate all sent ones to the user model before we clean them up. |
||
| Q(no_login_email_last_sent__lt=now - settings.NO_LOGIN_WAIT_TIME) | ||
| ) | ||
|
|
||
|
|
||
| @celery_app.task(name='scripts.triggered_no_login_email') | ||
|
|
@@ -133,6 +131,8 @@ def send_no_login_email(email_task_id: int): | |
| ) | ||
| email_task.status = 'SUCCESS' | ||
| email_task.save() | ||
| user.no_login_email_last_sent = timezone.now() | ||
| user.save() | ||
|
|
||
| except Exception as exc: # noqa: BLE001 | ||
| logger.exception(f'EmailTask {email_task.id}: error while sending') | ||
|
|
||
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
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.
Uh oh!
There was an error while loading. Please reload this page.