Skip to content

feat: limit number of environments per project (#3875)#7236

Open
kishore7860 wants to merge 1 commit intoFlagsmith:mainfrom
kishore7860:main
Open

feat: limit number of environments per project (#3875)#7236
kishore7860 wants to merge 1 commit intoFlagsmith:mainfrom
kishore7860:main

Conversation

@kishore7860
Copy link
Copy Markdown

Thanks for submitting a PR! Please check the boxes below:

  • [✅] I have read the Contributing Guide.

  • [✅] I have added information to docs/ if required so people know about the feature.

  • [✅] I have filled in the "Changes" section below.

  • [✅] I have filled in the "How did you test this code" section below.

  • Adds a max_environments_allowed field (default: 100) to the Project model to soft-limit the number of environments per project, mitigating N+1 query impact from the permission system

    • Enforces the limit on environment creation and cloning in EnvironmentPermissions, raising a clear ValidationError when exceeded
    • Exposes the field in ProjectRetrieveSerializer (read-only) and includes environments in the Project.is_too_large check

    Grandfathering existing clients

    Existing organisations already operating above the limit are not affected — admins can set max_environments_allowed to a higher value per project via the Django admin panel or API to accommodate them.

Changes

  • Adds a soft limit of 100 environments per project to mitigate N+1 query impact from the permission system. - Added max_environments_allowed field (default: 100) to the Project model, following the existing pattern of
    max_segments_allowed and max_features_allowed
  • Enforced the limit in EnvironmentPermissions for both create and clone actions, raising a ValidationError with a clear message when exceeded
  • Added environments count to the Project.is_too_large property
  • Exposed the field as read-only in ProjectRetrieveSerializer
  • Existing clients operating above the limit can be grandfathered by setting max_environments_allowed to a higher value per project via the Django admin panel

How did you test this code?

  • Added 5 unit tests for environment permissions:
    • test_environment_permissions__create_at_limit__raises_validation_error
    • test_environment_permissions__create_below_limit__returns_true
    • test_environment_permissions__clone_at_limit__raises_validation_error
    • test_environment_permissions__clone_below_limit__returns_true
    • test_environment_permissions__create_at_limit_with_increased_limit__returns_true (grandfathering)
    • Added 2 unit tests for the project model:
      • test_is_too_large__environments_exceed_limit__returns_true
      • test_is_too_large__environments_within_limit__returns_false
    • All files pass mypy --strict and ruff linting

@kishore7860 kishore7860 requested review from a team as code owners April 14, 2026 16:20
@kishore7860 kishore7860 requested review from emyller and removed request for a team April 14, 2026 16:20
Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 14, 2026

@kishore7860 is attempting to deploy a commit to the Flagsmith Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions bot added the api Issue related to the REST API label Apr 14, 2026
@emyller emyller requested a review from khvn26 April 14, 2026 16:22
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is kicking off a free cloud agent to fix this issue. This run is complimentary, but you can enable autofix for all future PRs in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ae138ad. Configure here.

"max_segments_allowed",
"max_features_allowed",
"max_segment_overrides_allowed",
"max_environments_allowed",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing admin panel field prevents limit grandfathering

High Severity

The new max_environments_allowed field is not added to ProjectAdmin.fields in admin.py, even though the PR description explicitly states admins can adjust it via the Django admin panel to grandfather existing clients. The field is also read_only in ProjectRetrieveSerializer, so there's no way to modify it through the API either. The other analogous fields (max_segments_allowed, max_features_allowed, max_segment_overrides_allowed) are all present in the admin fields tuple. Without this, existing projects at or above 100 environments are permanently locked out from creating new environments with no admin-accessible override.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit ae138ad. Configure here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bugbot Autofix determined this is a false positive.

This repository state has no max_environments_allowed model or serializer/admin field usage at all, so the reported missing admin field is not an actionable regression in this PR.

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.28%. Comparing base (1cd16ea) to head (ae138ad).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7236      +/-   ##
==========================================
- Coverage   98.29%   98.28%   -0.01%     
==========================================
  Files        1351     1352       +1     
  Lines       50747    50690      -57     
==========================================
- Hits        49880    49823      -57     
  Misses        867      867              

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@khvn26
Copy link
Copy Markdown
Member

khvn26 commented Apr 14, 2026

Thanks for the contribution @kishore7860 — have you considered creating (or linking an existing) issue describing the permissioning N+1 in question?

@kishore7860
Copy link
Copy Markdown
Author

Thanks for the review @khvn26! The original issue is #3875 — it describes the N+1 query patterns in the permission system and suggests a soft limit of 100 environments to mitigate the impact. I've updated the PR description to link it with Closes #3875.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nah, let's keep it.

project: Project,
) -> None:
# Given
from environments.models import Environment
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I wish I understood Claude's obsession with local imports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Issue related to the REST API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants