From 17ae19bc601fd5f2d7ef97b1914a95139de080cd Mon Sep 17 00:00:00 2001 From: ABHISHEK Date: Wed, 22 Jul 2026 14:51:16 +0530 Subject: [PATCH 1/3] Fixed the custom roles not listing issue --- api/dashboard/campus/events_views.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/api/dashboard/campus/events_views.py b/api/dashboard/campus/events_views.py index 7583519f..9cf60819 100644 --- a/api/dashboard/campus/events_views.py +++ b/api/dashboard/campus/events_views.py @@ -453,6 +453,11 @@ def get(self, request): roles.add(f"{chapter.ig.code} CampusLead") roles.add(f"{chapter.ig.code} IGLead") + # Custom execom roles created via POST + custom_execom_roles = Role.objects.filter(is_execom_role=True).values_list("title", flat=True) + for title in custom_execom_roles: + roles.add(title) + return CustomResponse(response={"data": sorted(list(roles))}).get_success_response() From c11b1aa21803f26d0828202d1906fdcd2d9d775b Mon Sep 17 00:00:00 2001 From: ABHISHEK Date: Wed, 22 Jul 2026 15:50:20 +0530 Subject: [PATCH 2/3] Fixed Leaking of roles in fetching --- api/dashboard/campus/events_views.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/api/dashboard/campus/events_views.py b/api/dashboard/campus/events_views.py index 9cf60819..365e1b6e 100644 --- a/api/dashboard/campus/events_views.py +++ b/api/dashboard/campus/events_views.py @@ -453,8 +453,12 @@ def get(self, request): roles.add(f"{chapter.ig.code} CampusLead") roles.add(f"{chapter.ig.code} IGLead") - # Custom execom roles created via POST - custom_execom_roles = Role.objects.filter(is_execom_role=True).values_list("title", flat=True) + + custom_execom_roles = Role.objects.filter( + is_execom_role=True + ).exclude( + title__endswith=" CampusLead" + ).values_list("title", flat=True) for title in custom_execom_roles: roles.add(title) From 10211f868929a50120d58a2a077c5fae70cebc48 Mon Sep 17 00:00:00 2001 From: ABHISHEK Date: Wed, 22 Jul 2026 21:23:56 +0530 Subject: [PATCH 3/3] Fixed the roles not listing issue + alumini not accurate issue --- api/dashboard/campus/events_views.py | 9 ++++--- mu_celery/alumni_cron.py | 37 ++++++++++++++++++++++++++++ mulearnbackend/celery.py | 5 +++- 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 mu_celery/alumni_cron.py diff --git a/api/dashboard/campus/events_views.py b/api/dashboard/campus/events_views.py index 365e1b6e..c88b7bb3 100644 --- a/api/dashboard/campus/events_views.py +++ b/api/dashboard/campus/events_views.py @@ -454,13 +454,16 @@ def get(self, request): roles.add(f"{chapter.ig.code} IGLead") + ig_campus_lead_titles = [ + RoleType.IG_CAMPUS_LEAD_ROLE(code) + for code in InterestGroup.objects.values_list("code", flat=True) + ] custom_execom_roles = Role.objects.filter( is_execom_role=True ).exclude( - title__endswith=" CampusLead" + title__in=ig_campus_lead_titles ).values_list("title", flat=True) - for title in custom_execom_roles: - roles.add(title) + roles.update(custom_execom_roles) return CustomResponse(response={"data": sorted(list(roles))}).get_success_response() diff --git a/mu_celery/alumni_cron.py b/mu_celery/alumni_cron.py new file mode 100644 index 00000000..2ec12ddf --- /dev/null +++ b/mu_celery/alumni_cron.py @@ -0,0 +1,37 @@ +from celery import shared_task +from django.db.models import Q +from django.utils.timezone import now + +from db.organization import UserOrganizationLink +from utils.types import OrganizationType + + +@shared_task +def update_alumni_status_cron(): + """Synchronize college alumni status with graduation year. + + A user is an alumnus only when their four-digit graduation year is before + the current year. This corrects both stale alumni and stale non-alumni + values, so it is safe to run repeatedly. + """ + current_year = str(now().year) + valid_college_links = UserOrganizationLink.objects.filter( + org__org_type=OrganizationType.COLLEGE.value, + graduation_year__regex=r"^[0-9]{4}$", + ) + + marked_alumni = valid_college_links.filter( + graduation_year__lt=current_year, + ).filter( + Q(is_alumni=False) | Q(is_alumni__isnull=True) + ).update(is_alumni=True) + + marked_student = valid_college_links.filter( + graduation_year__gte=current_year, + is_alumni=True, + ).update(is_alumni=False) + + return { + "marked_alumni": marked_alumni, + "marked_student": marked_student, + } diff --git a/mulearnbackend/celery.py b/mulearnbackend/celery.py index 02da45e9..b26689fc 100644 --- a/mulearnbackend/celery.py +++ b/mulearnbackend/celery.py @@ -5,7 +5,10 @@ # Set the default Django settings module for the 'celery' program. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mulearnbackend.settings") -app = Celery("mulearnbackend") +app = Celery( + "mulearnbackend", + include=["mu_celery.alumni_cron"], +) # Using a string here means the worker doesn't have to serialize # the configuration object to child processes.