Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pagination to joblistings #3792

Merged
merged 1 commit into from
Mar 26, 2025
Merged

Conversation

itsisak
Copy link
Contributor

@itsisak itsisak commented Mar 19, 2025

Description

Add pagination to joblistings, since now whenever anyone access api/v1/joblistings it returns all joblistings ever.
Disable pagination whenever filters are applied, to stay consistent with previous functionality.

This aims to improve speed of health check.

Testing

  • The code quality is at a minimum required level of quality, readability, and performance.
  • I have thoroughly tested my changes.

Tests work, so i guess... isss good?

Resolves ABA-1366

@itsisak itsisak added review-needed Pull requests that need review chore Pull requests that does something "boring", yet important, e.g. cleaning up code labels Mar 19, 2025
@itsisak itsisak self-assigned this Mar 19, 2025
Copy link

linear bot commented Mar 19, 2025

@eikhr
Copy link
Member

eikhr commented Mar 19, 2025

Have you added pagination to the frontend?

Copy link

coderabbitai bot commented Mar 19, 2025

📝 Walkthrough

Walkthrough

The changes add a new Boolean filter to the job listings filter set. A method named filter_time has been introduced to filter listings based on their visible_from and visible_to dates when the timeFilter is activated. In addition, modifications to the job listing view set remove the hard-coded time-based filtering and adjust pagination behavior. Pagination is now disabled generally when any filter parameters are provided rather than relying solely on the time filter.

Changes

File(s) Summary
lego/apps/joblistings/filters.py Added new BooleanFilter timeFilter in JoblistingFilterSet with a custom method filter_time that filters job listings based on current visibility dates.
lego/apps/joblistings/views.py Removed explicit time-based filtering and direct pagination disabling. Now, pagination is disabled if any filter parameters are applied in the request.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant FilterSet
    participant DB

    Client->>FilterSet: Request job listings with timeFilter parameter
    alt timeFilter is True
       FilterSet->>DB: Query listings where visible_from ≤ now ≤ visible_to
       DB-->>FilterSet: Return filtered listings
    else timeFilter is False
       FilterSet-->>Client: Return unmodified queryset
    end
Loading
sequenceDiagram
    participant Client
    participant ViewSet
    participant FilterSet
    participant DB

    Client->>ViewSet: API request with filter parameters
    ViewSet->>FilterSet: Apply filtering logic
    ViewSet->>ViewSet: Check if filter parameters are present
    alt Filters applied
       ViewSet->>ViewSet: Set pagination_class to None
    else
       ViewSet->>ViewSet: Use default pagination settings
    end
    ViewSet->>DB: Retrieve job listings (filtered or unfiltered)
    DB-->>ViewSet: Return queryset
    ViewSet-->>Client: Send response
Loading

Tip

⚡🧪 Multi-step agentic review comment chat (experimental)
  • We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments.
    - To enable this feature, set early_access to true under in the settings.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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 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.

Copy link

@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: 0

🧹 Nitpick comments (2)
lego/apps/joblistings/filters.py (1)

9-9: Consider using snake_case naming convention for consistency.

The filter name timeFilter uses camelCase, which is inconsistent with Python/Django naming conventions and the other filter created_after that uses snake_case. Consider renaming to time_filter for consistency.

-    timeFilter = BooleanFilter(method="filter_time")
+    time_filter = BooleanFilter(method="filter_time")
lego/apps/joblistings/views.py (1)

53-57: Consider a more explicit check for filter values.

The current implementation disables pagination if any filter parameter exists and has a non-empty value. For more precise control, consider explicitly checking if the filter values are meaningful rather than just present.

-        if params and any(
-            params.get(key) for key in self.filterset_class.get_filters()
-        ):
+        if params and any(
+            filter_value for key in self.filterset_class.get_filters()
+            if (filter_value := params.get(key)) and filter_value not in ('', 'false', '0')
+        ):
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9215fc6 and 960a1b5.

📒 Files selected for processing (2)
  • lego/apps/joblistings/filters.py (1 hunks)
  • lego/apps/joblistings/views.py (1 hunks)
🔇 Additional comments (3)
lego/apps/joblistings/filters.py (2)

1-2: Updated imports to support new time filtering functionality.

The addition of timezone and BooleanFilter imports supports the newly added time filtering capability.


15-20: Effective implementation of time-based filtering.

The filter_time method correctly filters job listings based on their visibility window when the filter is active. This implementation aligns with the PR objective of enhancing filtering capabilities while maintaining the ability to view all job listings when needed.

lego/apps/joblistings/views.py (1)

51-57:

❓ Verification inconclusive

Pagination is now disabled when any filter is applied.

Good implementation that disables pagination when any filter parameter is applied, aligning with the PR objective of maintaining consistency with existing functionality. The approach checks for the presence and non-emptiness of any filter parameter.

However, there might be a potential issue: if a parameter exists but has an empty or "false" value, pagination will still be disabled. Verify that this is the intended behavior.


🏁 Script executed:

#!/bin/bash
# Check if there are any cases where parameters with empty values are handled in the codebase
rg -A 2 -B 2 "params\.(get|getlist)\(.*\)" --glob "*.py" | grep -v "if not" | grep -v "if params\."

Length of output: 4593


Attention: Verify Filter Parameter Truthiness in Pagination Disabling

The current implementation in lego/apps/joblistings/views.py (lines 51–57) correctly disables pagination when any filter parameter is provided. The check using any(params.get(key) for key in self.filterset_class.get_filters()) evaluates the truthiness of each parameter. This means that if a parameter is present with a non-empty value (for example, "false" as a string), pagination will be disabled—even if the value might logically represent a false state. In contrast, an empty string would evaluate as false and not disable pagination.

Notably, similar patterns are found in other parts of the codebase, though there is some variation (e.g., an explicit check like if descendants == "true" in memberships). Please review the business logic to ensure that treating any non-empty value (including "false") as a trigger for disabling pagination is the intended behavior.

  • Confirm if parameters with values like "false" should indeed disable pagination.
  • Consider whether stricter type/value validations are necessary for specific filters.

@itsisak
Copy link
Contributor Author

itsisak commented Mar 19, 2025

Have you added pagination to the frontend?

No, but I believe there are no places in frontend that use this endpoint without filtering.

Copy link

codecov bot commented Mar 19, 2025

Codecov Report

Attention: Patch coverage is 90.00000% with 1 line in your changes missing coverage. Please review.

Project coverage is 89.96%. Comparing base (145b079) to head (960a1b5).
Report is 11 commits behind head on master.

Files with missing lines Patch % Lines
lego/apps/joblistings/filters.py 85.71% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3792      +/-   ##
==========================================
- Coverage   89.97%   89.96%   -0.01%     
==========================================
  Files         740      740              
  Lines       23962    23967       +5     
==========================================
+ Hits        21560    21563       +3     
- Misses       2402     2404       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@ivarnakken ivarnakken left a comment

Choose a reason for hiding this comment

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

Very nice!!


from lego.apps.joblistings.models import Joblisting


class JoblistingFilterSet(FilterSet):
created_after = DateFilter("created_at", lookup_expr="gte")
timeFilter = BooleanFilter(method="filter_time")
Copy link
Member

Choose a reason for hiding this comment

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

Wait is this correct? A Boolean?

Copy link
Member

Choose a reason for hiding this comment

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

Also, does it have to be camelCase?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wait is this correct? A Boolean?

What else? It is used like this api/v1/joblistings?timeFilter=true.

Also, does it have to be camelCase?

Since that is how it is written in the request (see above) it is how Django maps params. So in order to change it to it seems I would have to add custom logic for it and I dont think that is worth it. Also there are other instances where camelCase is used in similar scenarios.

Copy link
Member

@jonasdeluna jonasdeluna left a comment

Choose a reason for hiding this comment

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

Why does pagination have to be disabled when filtering?

@itsisak
Copy link
Contributor Author

itsisak commented Mar 20, 2025

Hopefully resolves webkom/uptime#99

@itsisak
Copy link
Contributor Author

itsisak commented Mar 20, 2025

Why does pagination have to be disabled when filtering?

It really should not in my opinion, however my goal here was mainly to improve the healthcheck taking forever and did not want to update all the usages in frontend to handle pagination. Since the frontend never uses the endpoint without filtering (only the healthcheck do) this should keep the current functionality for joblistings.

@itsisak itsisak merged commit 5c6604b into master Mar 26, 2025
3 checks passed
@itsisak itsisak deleted the add-pagination-to-joblistings branch March 26, 2025 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore Pull requests that does something "boring", yet important, e.g. cleaning up code review-needed Pull requests that need review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants