Skip to content

Conversation

@upsetbit
Copy link

@upsetbit upsetbit commented Nov 14, 2025

Description

In Plane CE v1.1.0 the project issues list endpoint (IssueListCreateAPIEndpoint) is not wired to DRF’s filter stack, so query params such as priority=urgent are ignored and pagination counts reflect the entire project instead of the filtered subset. This patch imports the existing ComplexFilterBackend, IssueFilterSet, and legacy issue_filters, applying them to both the result and total-count querysets so the REST API mirrors the in-product filtering behavior.

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)

Not applicable

Test Scenarios

  1. curl https://plane.domain.tld/api/v1/workspaces/<slug>/projects/<project_id>/issues/?priority=urgent
    • Before (v1.1.0 community): returned mixed priorities and total counts for the entire project.
    • After this patch: only urgent issues appear and count/total_results match the filtered subset.
  2. Similar verification with state_group filters to ensure other query params work as expected.

References

Not applicable

Summary by CodeRabbit

  • New Features
    • Introduces advanced JSON-based filtering for issue lists, enabling richer, multi-criteria queries to find and organize issues more effectively.
    • Restores support for legacy query parameters so older filters continue to work.
    • Applies filtering consistently to both list results and total counts, improving accuracy of displayed issue totals.

@CLAassistant
Copy link

CLAassistant commented Nov 14, 2025

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 14, 2025

Walkthrough

The IssueListCreateAPIEndpoint in apps/api/plane/api/views/issue.py is configured with filter_backends and filterset_class, and its GET flow now applies JSON-based filters via filter_queryset() and legacy filters via issue_filters() to both issue querysets.

Changes

Cohort / File(s) Summary
Issue endpoint filtering enhancement
apps/api/plane/api/views/issue.py
Added imports for ComplexFilterBackend, IssueFilterSet, and issue_filters. Set class attributes filter_backends = (ComplexFilterBackend,) and filterset_class = IssueFilterSet on IssueListCreateAPIEndpoint. Updated GET flow to call filter_queryset() on issue_queryset and total_issue_queryset, then apply legacy issue_filters() to both querysets when present.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Endpoint as IssueListCreateAPIEndpoint
    participant Backend as ComplexFilterBackend
    participant Legacy as issue_filters

    Client->>Endpoint: GET /issues (with JSON or query params)

    rect rgb(200,220,255)
    Note over Endpoint,Backend: JSON filter phase
    Endpoint->>Backend: filter_queryset(issue_queryset)
    Backend-->>Endpoint: filtered_issue_queryset
    Endpoint->>Backend: filter_queryset(total_issue_queryset)
    Backend-->>Endpoint: filtered_total_issue_queryset
    end

    rect rgb(220,200,255)
    Note over Endpoint,Legacy: Legacy query-param phase
    Endpoint->>Legacy: issue_filters(request.query_params, "GET")
    Legacy-->>Endpoint: legacy_filters (if any)
    Endpoint->>Endpoint: apply legacy_filters to both querysets
    end

    Endpoint-->>Client: paginated & filtered issue response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review application of filters to both issue_queryset and total_issue_queryset to ensure counts remain consistent.
  • Confirm ordering (JSON filters first, legacy filters second) is intentional and doesn't conflict.
  • Verify IssueFilterSet mapping matches expected filter fields.

Poem

🐇 I hop through code with gentle paws,
Filters old and new align their laws.
JSON first, then legacy too—
Issue lists tidy, clear in view. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title 'Fix issue filters on list endpoint' is concise, clear, and directly describes the main change—enabling filtering on the issues list endpoint.
Description check ✅ Passed The pull request description is comprehensive and follows the template with all major sections filled out, including a detailed description of the bug, type of change, test scenarios, and acknowledgment of N/A sections.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 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 b3ea1a2 and 28e0281.

📒 Files selected for processing (1)
  • apps/api/plane/api/views/issue.py (3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: NarayanBavisetti
Repo: makeplane/plane PR: 7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
Learnt from: NarayanBavisetti
Repo: makeplane/plane PR: 7905
File: apps/api/plane/app/views/search/base.py:241-276
Timestamp: 2025-10-29T09:17:54.815Z
Learning: In apps/api/plane/app/views/search/base.py, the `filter_intakes` method uses `Issue.objects` (base manager) instead of `Issue.issue_objects` (custom manager) because the custom manager filters out all intake statuses, which would prevent querying pending and snoozed intake issues.
📚 Learning: 2025-10-29T09:17:54.815Z
Learnt from: NarayanBavisetti
Repo: makeplane/plane PR: 7905
File: apps/api/plane/app/views/search/base.py:241-276
Timestamp: 2025-10-29T09:17:54.815Z
Learning: In apps/api/plane/app/views/search/base.py, the `filter_intakes` method uses `Issue.objects` (base manager) instead of `Issue.issue_objects` (custom manager) because the custom manager filters out all intake statuses, which would prevent querying pending and snoozed intake issues.

Applied to files:

  • apps/api/plane/api/views/issue.py
📚 Learning: 2025-07-23T18:18:06.875Z
Learnt from: NarayanBavisetti
Repo: makeplane/plane PR: 7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.

Applied to files:

  • apps/api/plane/api/views/issue.py
🧬 Code graph analysis (1)
apps/api/plane/api/views/issue.py (5)
apps/api/plane/utils/filters/filter_backend.py (1)
  • ComplexFilterBackend (10-313)
apps/api/plane/utils/filters/filterset.py (1)
  • IssueFilterSet (120-262)
apps/api/plane/utils/issue_filters.py (1)
  • issue_filters (424-459)
apps/api/plane/api/views/base.py (1)
  • filter_queryset (55-58)
apps/api/plane/app/views/base.py (1)
  • filter_queryset (158-161)
🔇 Additional comments (3)
apps/api/plane/api/views/issue.py (3)

53-54: LGTM! Imports are correct.

The imports correctly bring in the JSON-based filtering infrastructure (ComplexFilterBackend, IssueFilterSet) and legacy filtering utility (issue_filters) needed to fix the endpoint filtering.


250-251: LGTM! Filter configuration correctly placed.

The filter_backends and filterset_class attributes are now correctly added to IssueListCreateAPIEndpoint, which addresses the issue identified in previous reviews. This configuration enables DRF's filter stack to process JSON-based filters via the ComplexFilterBackend.


350-358: LGTM! Filtering logic correctly implements dual-filter support.

The implementation correctly applies both JSON-based filters (via self.filter_queryset()) and legacy query parameter filters (via issue_filters()) to both the result queryset and the count queryset. This ensures:

  1. The JSON filters parameter is processed by ComplexFilterBackend
  2. Legacy query parameters (e.g., priority=urgent) continue to work
  3. Pagination counts reflect the filtered subset, not the entire project

This directly addresses the issue described in the PR objectives where filters were previously ignored.


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

Comment @coderabbitai help to get the list of available commands and usage tips.

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: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c04ae51 and b3ea1a2.

📒 Files selected for processing (1)
  • apps/api/plane/api/views/issue.py (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: NarayanBavisetti
Repo: makeplane/plane PR: 7460
File: apps/api/plane/app/serializers/draft.py:112-122
Timestamp: 2025-07-23T18:18:06.875Z
Learning: In the Plane codebase serializers, workspace_id is not consistently passed in serializer context, so parent issue validation in DraftIssueCreateSerializer only checks project_id rather than both workspace_id and project_id. The existing project member authentication system already validates that users can only access projects they belong to, providing sufficient security without risking breaking functionality by adding workspace_id validation where the context might not be available.
Learnt from: NarayanBavisetti
Repo: makeplane/plane PR: 7905
File: apps/api/plane/app/views/search/base.py:241-276
Timestamp: 2025-10-29T09:17:54.815Z
Learning: In apps/api/plane/app/views/search/base.py, the `filter_intakes` method uses `Issue.objects` (base manager) instead of `Issue.issue_objects` (custom manager) because the custom manager filters out all intake statuses, which would prevent querying pending and snoozed intake issues.
📚 Learning: 2025-10-29T09:17:54.815Z
Learnt from: NarayanBavisetti
Repo: makeplane/plane PR: 7905
File: apps/api/plane/app/views/search/base.py:241-276
Timestamp: 2025-10-29T09:17:54.815Z
Learning: In apps/api/plane/app/views/search/base.py, the `filter_intakes` method uses `Issue.objects` (base manager) instead of `Issue.issue_objects` (custom manager) because the custom manager filters out all intake statuses, which would prevent querying pending and snoozed intake issues.

Applied to files:

  • apps/api/plane/api/views/issue.py
🧬 Code graph analysis (1)
apps/api/plane/api/views/issue.py (5)
apps/api/plane/utils/filters/filter_backend.py (1)
  • ComplexFilterBackend (10-313)
apps/api/plane/utils/filters/filterset.py (1)
  • IssueFilterSet (120-262)
apps/api/plane/utils/issue_filters.py (1)
  • issue_filters (424-459)
apps/api/plane/api/views/base.py (1)
  • filter_queryset (55-58)
apps/api/plane/app/views/base.py (1)
  • filter_queryset (158-161)
🔇 Additional comments (1)
apps/api/plane/api/views/issue.py (1)

53-54: LGTM: Imports are correct.

The imports for ComplexFilterBackend, IssueFilterSet, and issue_filters are properly structured and match the available utilities.

Move filter_backends and filterset_class from WorkspaceIssueAPIEndpoint
to IssueListCreateAPIEndpoint where self.filter_queryset() is actually called.

This resolves the issue identified by CodeRabbit review where the filter
configuration was on a different class than where it was being used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants