From ccda7a41e0ff0c3d5c57d30c77d5ffd32bbe20f1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 07:13:09 +0000 Subject: [PATCH 1/3] Initial plan From 96ced4ecfcf778426cd544894607403a55e7ff2e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 07:16:33 +0000 Subject: [PATCH 2/3] refactor: optimize log_invalid query pattern in with_role method Co-authored-by: mihow <158175+mihow@users.noreply.github.com> --- ami/main/models.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/ami/main/models.py b/ami/main/models.py index bd1993469..22fe635a6 100644 --- a/ami/main/models.py +++ b/ami/main/models.py @@ -557,16 +557,21 @@ def with_role(self, log_invalid=False): # Log invalid memberships if requested (before filtering them out) if log_invalid: - invalid = queryset.filter(has_role=False).select_related("user", "project") - if invalid.exists(): - for membership in invalid: - logger.warning( - f"Data inconsistency detected: UserProjectMembership {membership.pk} " - f"for user '{membership.user.email}' in project '{membership.project.name}' " - f"(ID: {membership.project.pk}) has no role assigned. This indicates " - f"the permission groups are out of sync. " - f"Fix by running: python manage.py update_roles --project-id={membership.project.pk}" - ) + # Use a single query to get both count and unique project IDs + invalid_projects = list( + queryset.filter(has_role=False) + .values_list("project_id", flat=True) + .distinct() + ) + if invalid_projects: + invalid_count = queryset.filter(has_role=False).count() + projects_str = ", ".join(str(pid) for pid in invalid_projects) + logger.warning( + f"Data inconsistency detected: {invalid_count} UserProjectMembership(s) " + f"without assigned roles found in project(s): {projects_str}. " + f"This indicates permission groups are out of sync. " + f"Fix by running: python manage.py update_roles --project-id=" + ) # Return only members with valid roles return queryset.filter(has_role=True) From 29320bd7153166eb550477deae1eb1223d0ef4f6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 07:17:36 +0000 Subject: [PATCH 3/3] refactor: optimize to single query using annotate Co-authored-by: mihow <158175+mihow@users.noreply.github.com> --- ami/main/models.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/ami/main/models.py b/ami/main/models.py index 22fe635a6..2307afc06 100644 --- a/ami/main/models.py +++ b/ami/main/models.py @@ -557,15 +557,19 @@ def with_role(self, log_invalid=False): # Log invalid memberships if requested (before filtering them out) if log_invalid: - # Use a single query to get both count and unique project IDs - invalid_projects = list( + from django.db.models import Count + + # Single query to get project IDs and their invalid membership counts + invalid_by_project = list( queryset.filter(has_role=False) - .values_list("project_id", flat=True) - .distinct() + .values("project_id") + .annotate(count=Count("id")) ) - if invalid_projects: - invalid_count = queryset.filter(has_role=False).count() - projects_str = ", ".join(str(pid) for pid in invalid_projects) + + if invalid_by_project: + invalid_count = sum(item["count"] for item in invalid_by_project) + project_ids = [item["project_id"] for item in invalid_by_project] + projects_str = ", ".join(str(pid) for pid in project_ids) logger.warning( f"Data inconsistency detected: {invalid_count} UserProjectMembership(s) " f"without assigned roles found in project(s): {projects_str}. "