From c7965318cc4ffe6c04cbf3bce5ed897df0462260 Mon Sep 17 00:00:00 2001 From: sangeethailango Date: Tue, 15 Jul 2025 18:25:51 +0530 Subject: [PATCH 1/4] fix: filter out removed project members from wi assignees --- apps/api/plane/app/views/issue/base.py | 3 +++ apps/api/plane/app/views/issue/relation.py | 1 + apps/api/plane/app/views/issue/sub_issue.py | 1 + apps/api/plane/utils/grouper.py | 9 +++++++-- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/api/plane/app/views/issue/base.py b/apps/api/plane/app/views/issue/base.py index d0b4e7d5e08..ecaf41c0b2c 100644 --- a/apps/api/plane/app/views/issue/base.py +++ b/apps/api/plane/app/views/issue/base.py @@ -505,6 +505,7 @@ def retrieve(self, request, slug, project_id, pk=None): filter=Q( ~Q(assignees__id__isnull=True) & Q(assignees__member_project__is_active=True) + & Q(assignees__member_project__project_id=project_id) & Q(issue_assignee__deleted_at__isnull=True) ), ), @@ -914,6 +915,7 @@ def list(self, request, slug, project_id): ~Q(assignees__id__isnull=True) & Q(assignees__member_project__is_active=True) & Q(issue_assignee__deleted_at__isnull=True) + & Q(assignees__member_project__project_id=project_id) ), ), Value([], output_field=ArrayField(UUIDField())), @@ -1253,6 +1255,7 @@ def get(self, request, slug, project_identifier, issue_identifier): ~Q(assignees__id__isnull=True) & Q(assignees__member_project__is_active=True) & Q(issue_assignee__deleted_at__isnull=True) + & Q(assignees__member_project__project_id=project.id) ), ), Value([], output_field=ArrayField(UUIDField())), diff --git a/apps/api/plane/app/views/issue/relation.py b/apps/api/plane/app/views/issue/relation.py index 50d319a88e7..7f7fe5ce6aa 100644 --- a/apps/api/plane/app/views/issue/relation.py +++ b/apps/api/plane/app/views/issue/relation.py @@ -149,6 +149,7 @@ def list(self, request, slug, project_id, issue_id): ~Q(assignees__id__isnull=True) & Q(assignees__member_project__is_active=True) & Q(issue_assignee__deleted_at__isnull=True) + & Q(assignees__member_project__project_id=project_id) ), ), Value([], output_field=ArrayField(UUIDField())), diff --git a/apps/api/plane/app/views/issue/sub_issue.py b/apps/api/plane/app/views/issue/sub_issue.py index 0843a9a512b..1e85695a73e 100644 --- a/apps/api/plane/app/views/issue/sub_issue.py +++ b/apps/api/plane/app/views/issue/sub_issue.py @@ -83,6 +83,7 @@ def get(self, request, slug, project_id, issue_id): ~Q(assignees__id__isnull=True) & Q(assignees__member_project__is_active=True) & Q(issue_assignee__deleted_at__isnull=True) + & Q(assignees__member_project__project_id=project_id) ), ), Value([], output_field=ArrayField(UUIDField())), diff --git a/apps/api/plane/utils/grouper.py b/apps/api/plane/utils/grouper.py index 89e154a7f75..5a6cd94a741 100644 --- a/apps/api/plane/utils/grouper.py +++ b/apps/api/plane/utils/grouper.py @@ -1,7 +1,7 @@ # Django imports from django.contrib.postgres.aggregates import ArrayAgg from django.contrib.postgres.fields import ArrayField -from django.db.models import Q, UUIDField, Value, QuerySet +from django.db.models import Q, UUIDField, Value, QuerySet, OuterRef from django.db.models.functions import Coalesce # Module imports @@ -23,6 +23,8 @@ def issue_queryset_grouper( group_by: Optional[str], sub_group_by: Optional[str], ) -> QuerySet[Issue]: + project_id = queryset.values_list("project_id", flat=True).first() + FIELD_MAPPER: Dict[str, str] = { "label_ids": "labels__id", "assignee_ids": "assignees__id", @@ -42,7 +44,10 @@ def issue_queryset_grouper( annotations_map: Dict[str, Tuple[str, Q]] = { "assignee_ids": ( "assignees__id", - ~Q(assignees__id__isnull=True) & Q(issue_assignee__deleted_at__isnull=True), + ~Q(assignees__id__isnull=True) + & Q(issue_assignee__deleted_at__isnull=True) + & Q(assignees__member_project__is_active=True) + & Q(assignees__member_project__project_id=project_id), ), "label_ids": ( "labels__id", From ce1e06a64997498f73aae3a17fad101a2971f4c3 Mon Sep 17 00:00:00 2001 From: sangeethailango Date: Wed, 16 Jul 2025 20:10:54 +0530 Subject: [PATCH 2/4] fix: project lead and default assignee of inactive member --- apps/api/plane/app/views/project/base.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/apps/api/plane/app/views/project/base.py b/apps/api/plane/app/views/project/base.py index 2728bf4de44..62e90f6788c 100644 --- a/apps/api/plane/app/views/project/base.py +++ b/apps/api/plane/app/views/project/base.py @@ -219,8 +219,21 @@ def retrieve(self, request, slug, pk): ) .filter(archived_at__isnull=True) .filter(pk=pk) + .prefetch_related("project_projectmember") ).first() + project_member_ids = ProjectMember.objects.filter( + project_id=pk, is_active=True + ).values_list("member_id", flat=True) + + members_ids = set(project_member_ids) + + if project.project_lead_id not in members_ids: + project.project_lead = None + + if project.default_assignee_id not in members_ids: + project.default_assignee = None + if project is None: return Response( {"error": "Project does not exist"}, status=status.HTTP_404_NOT_FOUND From 2a58081d66903ba64faf61be7bd23495987b9d0c Mon Sep 17 00:00:00 2001 From: sangeethailango Date: Thu, 17 Jul 2025 13:53:43 +0530 Subject: [PATCH 3/4] fix: inactive members in list of cycles --- apps/api/plane/app/views/cycle/base.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/api/plane/app/views/cycle/base.py b/apps/api/plane/app/views/cycle/base.py index bcce69bf85f..ee88ca9d901 100644 --- a/apps/api/plane/app/views/cycle/base.py +++ b/apps/api/plane/app/views/cycle/base.py @@ -174,6 +174,14 @@ def get_queryset(self): Q( issue_cycle__issue__issue_assignee__deleted_at__isnull=True ) + ) + & Q( + issue_cycle__issue__assignees__member_project__project_id=self.kwargs.get( + "project_id" + ) + ) + & Q( + issue_cycle__issue__assignees__member_project__is_active=True ), ), Value([], output_field=ArrayField(UUIDField())), From 8a1911c703ce7e852277f45f4a1d299207843cfd Mon Sep 17 00:00:00 2001 From: sangeethailango Date: Thu, 24 Jul 2025 14:32:35 +0530 Subject: [PATCH 4/4] fix: null reference in project_lead and default_assignee check --- apps/api/plane/app/views/project/base.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/api/plane/app/views/project/base.py b/apps/api/plane/app/views/project/base.py index 62e90f6788c..34198413912 100644 --- a/apps/api/plane/app/views/project/base.py +++ b/apps/api/plane/app/views/project/base.py @@ -222,6 +222,11 @@ def retrieve(self, request, slug, pk): .prefetch_related("project_projectmember") ).first() + if project is None: + return Response( + {"error": "Project does not exist"}, status=status.HTTP_404_NOT_FOUND + ) + project_member_ids = ProjectMember.objects.filter( project_id=pk, is_active=True ).values_list("member_id", flat=True) @@ -234,11 +239,6 @@ def retrieve(self, request, slug, pk): if project.default_assignee_id not in members_ids: project.default_assignee = None - if project is None: - return Response( - {"error": "Project does not exist"}, status=status.HTTP_404_NOT_FOUND - ) - recent_visited_task.delay( slug=slug, project_id=pk,