Skip to content

[WEB-2576] fix: inactive members as issue assignees#7415

Closed
sangeethailango wants to merge 4 commits intopreviewfrom
fix-inactive-member
Closed

[WEB-2576] fix: inactive members as issue assignees#7415
sangeethailango wants to merge 4 commits intopreviewfrom
fix-inactive-member

Conversation

@sangeethailango
Copy link
Member

@sangeethailango sangeethailango commented Jul 15, 2025

Description

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

Test Scenarios

References

Summary by CodeRabbit

  • Bug Fixes

    • Improved filtering of assignees to include only active members of the current project across issue, cycle, sub-issue, and relation views.
    • Project details now correctly reflect the active status of the project lead and default assignee.
  • Performance

    • Optimized project detail retrieval by prefetching related project members for faster access.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 15, 2025

Walkthrough

Filtering logic for aggregating assignee IDs was tightened across multiple API viewsets and utility functions. Now, only active project members associated with the current project are included as assignees when annotating querysets. Additionally, project retrieval now ensures that only active members can be assigned as project leads or default assignees.

Changes

File(s) Change Summary
apps/api/plane/app/views/cycle/base.py Enhanced assignee annotation in CycleViewSet.get_queryset to filter by active project members of current project.
apps/api/plane/app/views/issue/base.py Added project-specific and active member filters to assignee aggregation in IssueViewSet, IssuePaginatedViewSet, and IssueDetailIdentifierEndpoint.
apps/api/plane/app/views/issue/relation.py Restricted assignee annotation in IssueRelationViewSet.list to active members of the current project.
apps/api/plane/app/views/issue/sub_issue.py Added project-specific filter to assignee annotation for sub-issues.
apps/api/plane/app/views/project/base.py Modified ProjectViewSet.retrieve to prefetch project members and nullify lead/assignee if not active members.
apps/api/plane/utils/grouper.py Tightened assignee annotation to only include active members of the relevant project in issue_queryset_grouper.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API_ViewSet
    participant DB

    Client->>API_ViewSet: Request issues/cycles/sub-issues/relations
    API_ViewSet->>DB: Query with filters (project_id, is_active)
    DB-->>API_ViewSet: Filtered results (only active project members as assignees)
    API_ViewSet-->>Client: Response with assignee_ids (project-scoped, active)
Loading
sequenceDiagram
    participant Client
    participant ProjectViewSet
    participant DB

    Client->>ProjectViewSet: Request project details
    ProjectViewSet->>DB: Fetch project with prefetch (project_projectmember)
    ProjectViewSet->>DB: Query active ProjectMember IDs
    alt Lead/Assignee not active
        ProjectViewSet->>ProjectViewSet: Set project_lead/default_assignee to None
    end
    ProjectViewSet-->>Client: Return project details
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Suggested labels

🐛bug, ready to merge

Suggested reviewers

  • prateekshourya29
  • dheeru0198

Poem

In the burrows of code, a rabbit did see,
Filters for assignees, as strict as can be.
Only active project friends,
In queries now make amends.
With a hop and a fix,
The project’s in the mix—
Bugs chased away, as quick as can be! 🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2a58081 and 8a1911c.

📒 Files selected for processing (1)
  • apps/api/plane/app/views/project/base.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/api/plane/app/views/project/base.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-inactive-member

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sangeethailango sangeethailango changed the title fix: inactive members as issue assignees [WEB-2576] fix: inactive members as issue assignees Jul 21, 2025
@makeplane
Copy link

makeplane bot commented Jul 21, 2025

Pull Request Linked with Plane Work Items

Comment Automatically Generated by Plane

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/api/plane/utils/grouper.py (1)

4-4: Note: Unused import detected.

The OuterRef import appears to be unused in the visible code. Consider removing it if it's not needed elsewhere in the file.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2058f06 and 2a58081.

📒 Files selected for processing (6)
  • apps/api/plane/app/views/cycle/base.py (1 hunks)
  • apps/api/plane/app/views/issue/base.py (3 hunks)
  • apps/api/plane/app/views/issue/relation.py (1 hunks)
  • apps/api/plane/app/views/issue/sub_issue.py (1 hunks)
  • apps/api/plane/app/views/project/base.py (1 hunks)
  • apps/api/plane/utils/grouper.py (3 hunks)
🧠 Learnings (1)
apps/api/plane/app/views/issue/base.py (1)

Learnt from: vamsikrishnamathala
PR: #7214
File: web/core/store/issue/helpers/base-issues.store.ts:117-117
Timestamp: 2025-06-16T07:23:39.497Z
Learning: In the updateIssueDates method of BaseIssuesStore (web/core/store/issue/helpers/base-issues.store.ts), the projectId parameter is intentionally made optional to support override implementations in subclasses. The base implementation requires projectId and includes an early return check, but making it optional allows derived classes to override the method with different parameter requirements.

🧰 Additional context used
🧠 Learnings (1)
apps/api/plane/app/views/issue/base.py (1)

Learnt from: vamsikrishnamathala
PR: #7214
File: web/core/store/issue/helpers/base-issues.store.ts:117-117
Timestamp: 2025-06-16T07:23:39.497Z
Learning: In the updateIssueDates method of BaseIssuesStore (web/core/store/issue/helpers/base-issues.store.ts), the projectId parameter is intentionally made optional to support override implementations in subclasses. The base implementation requires projectId and includes an early return check, but making it optional allows derived classes to override the method with different parameter requirements.

🔇 Additional comments (9)
apps/api/plane/app/views/issue/sub_issue.py (1)

86-86: LGTM: Project-scoped assignee filtering correctly implemented.

The addition of the project ID filter ensures that assignees are properly scoped to the current project, preventing cross-project assignee leakage in sub-issue queries.

apps/api/plane/app/views/issue/relation.py (1)

152-152: LGTM: Consistent project-scoped filtering applied to issue relations.

The project ID filter correctly restricts assignees to the current project context in issue relation queries, maintaining consistency with other issue views.

apps/api/plane/app/views/issue/base.py (3)

508-508: LGTM: Project scoping added to issue retrieve method.

The project ID filter correctly ensures that assignees are limited to active members of the current project in issue retrieval.


918-918: LGTM: Project scoping added to paginated issue list.

The project ID filter properly restricts assignees to the current project in the paginated issue listing functionality.


1258-1258: LGTM: Project scoping added to issue detail identifier endpoint.

The use of project.id is correct here since project is a Project instance. This ensures assignees are properly scoped to the current project when retrieving issues by identifier.

apps/api/plane/utils/grouper.py (2)

26-26: LGTM: Project ID extraction for filtering logic.

Extracting the project ID from the queryset is the correct approach to enable project-scoped filtering in the utility function.


47-50: LGTM: Comprehensive assignee filtering logic implemented.

The updated filter conditions correctly ensure that:

  1. Assignee IDs are not null
  2. Issue assignee relationships are not soft-deleted
  3. Member projects are active
  4. Members belong to the current project

This provides robust filtering to prevent inactive members from being included as assignees.

apps/api/plane/app/views/project/base.py (1)

222-222: LGTM: Prefetching project members for efficiency.

Adding prefetch_related for project members is a good optimization for the subsequent member validation logic.

apps/api/plane/app/views/cycle/base.py (1)

177-185: Excellent fix for filtering inactive members as assignees!

The additional filtering conditions properly restrict assignees to only active project members associated with the current project. This ensures data integrity by preventing inactive members from being included in the assignee aggregation, which directly addresses the bug described in the PR objectives.

The implementation correctly combines:

  • Project membership validation (member_project__project_id)
  • Active status validation (member_project__is_active=True)
  • Existing deletion status check (issue_assignee__deleted_at__isnull=True)

"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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sangeethailango Why is this filter checking different field than the others?

@dheeru0198 dheeru0198 requested a review from Copilot July 23, 2025 12:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request fixes a bug related to inactive members being included as issue assignees. The changes ensure that only active project members are returned in assignee lists across various issue-related views and components.

  • Enhanced filtering logic to include project membership validation for assignees
  • Added project-specific filtering to prevent cross-project member assignments
  • Updated project details to nullify inactive project leads and default assignees

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
apps/api/plane/utils/grouper.py Added project-specific active member filtering for issue assignee grouping
apps/api/plane/app/views/project/base.py Modified project retrieval to nullify inactive project leads and default assignees
apps/api/plane/app/views/issue/sub_issue.py Added project ID filtering for sub-issue assignees
apps/api/plane/app/views/issue/relation.py Added project ID filtering for related issue assignees
apps/api/plane/app/views/issue/base.py Added project ID filtering across multiple issue view methods
apps/api/plane/app/views/cycle/base.py Enhanced cycle assignee filtering with project membership validation
Comments suppressed due to low confidence (1)

apps/api/plane/app/views/project/base.py:229

  • [nitpick] The variable name 'members_ids' should be 'member_ids' to be consistent with the source variable 'project_member_ids'.
        members_ids = set(project_member_ids)

@sangeethailango sangeethailango marked this pull request as draft July 24, 2025 09:53
@sriramveeraghanta sriramveeraghanta deleted the fix-inactive-member branch September 4, 2025 12:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants