Migrate Fuzz tests tool to Schemathesis and add REST Fuzz tests#3122
Conversation
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughDelegate fuzz orchestration to a reusable GitHub Actions workflow; add Schemathesis-based GraphQL and REST fuzz tests and runtime artifacts; add null-byte blocking middleware and ValidationError schema/handler; introduce Redis auth toggle; add trigram/Gin indexes and migrations; migrate many Strawberry resolvers to strawberry_django and update tests. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
|
PR validation failed: No linked issue and no valid closing issue reference in PR description |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
backend/docker/fuzz/tests/test_graphql.py (1)
8-13: Consider extracting headers to reduce duplication.The CSRF headers are defined twice: once for schema loading and once in the test function. Extracting to a constant would follow DRY principles.
🔎 Proposed refactor
CSRF_TOKEN = os.getenv("CSRF_TOKEN") +CSRF_HEADERS = {"X-CSRFToken": CSRF_TOKEN, "Cookie": f"csrftoken={CSRF_TOKEN}"} schema = schemathesis.graphql.from_url( f"{os.getenv('BASE_URL')}/graphql/", - headers={"X-CSRFToken": CSRF_TOKEN, "Cookie": f"csrftoken={CSRF_TOKEN}"}, + headers=CSRF_HEADERS, timeout=30, wait_for_schema=10.0, ) @schema.parametrize() def test_graphql_api(case): """Test GraphQL API endpoints.""" - case.call_and_validate( - headers={"X-CSRFToken": CSRF_TOKEN, "Cookie": f"csrftoken={CSRF_TOKEN}"} - ) + case.call_and_validate(headers=CSRF_HEADERS)Also applies to: 19-21
backend/docker/fuzz/entrypoint.sh (1)
19-21: Consider parameterizing max-examples for flexibility.The
generation.max-examplesvalue is hardcoded to 500. Making this configurable via an environment variable would allow different test scenarios without modifying the script.🔎 Proposed enhancement
echo "CSRF token retrieved: $CSRF_TOKEN" :> ./schemathesis.toml -echo "generation.max-examples = 500" >> ./schemathesis.toml +echo "generation.max-examples = ${SCHEMATHESIS_MAX_EXAMPLES:-500}" >> ./schemathesis.toml echo "Starting fuzzing process..." pytest ./tests/${TEST_FILE}backend/docker/fuzz/tests/test_rest.py (1)
8-13: Consider extracting headers to reduce duplication.The CSRF headers are duplicated between schema loading and test execution. Extracting to a constant would improve maintainability.
🔎 Proposed refactor
CSRF_TOKEN = os.getenv("CSRF_TOKEN") +CSRF_HEADERS = {"X-CSRFToken": CSRF_TOKEN, "Cookie": f"csrftoken={CSRF_TOKEN}"} schema = schemathesis.openapi.from_url( f"{os.getenv('REST_URL')}/openapi.json", - headers={"X-CSRFToken": CSRF_TOKEN, "Cookie": f"csrftoken={CSRF_TOKEN}"}, + headers=CSRF_HEADERS, timeout=30, wait_for_schema=10.0, ) @schema.parametrize() def test_rest_api(case): """Test REST API endpoints.""" - case.call_and_validate( - headers={"X-CSRFToken": CSRF_TOKEN, "Cookie": f"csrftoken={CSRF_TOKEN}"} - ) + case.call_and_validate(headers=CSRF_HEADERS)Also applies to: 19-21
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
.github/workflows/run-ci-cd.yamlbackend/Makefilebackend/docker/entrypoint.fuzz.shbackend/docker/fuzz/Dockerfilebackend/docker/fuzz/entrypoint.shbackend/docker/fuzz/tests/__init__.pybackend/docker/fuzz/tests/test_graphql.pybackend/docker/fuzz/tests/test_rest.pycspell/custom-dict.txtdocker-compose/fuzz.yaml
💤 Files with no reviewable changes (1)
- backend/docker/entrypoint.fuzz.sh
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
📚 Learning: 2025-12-26T06:57:30.908Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Applied to files:
backend/docker/fuzz/entrypoint.sh.github/workflows/run-ci-cd.yamlbackend/docker/fuzz/Dockerfilebackend/Makefilebackend/docker/fuzz/tests/test_graphql.py
📚 Learning: 2025-12-26T06:09:08.868Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 3041
File: .github/workflows/run-ci-cd.yaml:233-243
Timestamp: 2025-12-26T06:09:08.868Z
Learning: For the OWASP/Nest repository, Redis image versions should remain consistent across all environments (production, staging, local, E2E, and CI/CD E2E tests). When upgrading Redis, update all docker-compose files and CI/CD workflow configurations together to maintain environment parity.
Applied to files:
.github/workflows/run-ci-cd.yamlbackend/Makefile
📚 Learning: 2025-12-21T19:03:59.068Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: .github/workflows/setup-backend-environment/action.yaml:16-27
Timestamp: 2025-12-21T19:03:59.068Z
Learning: Composite actions (runs: using: composite) execute as steps within the calling job's context and can access the job context, including job.services.* properties (e.g., job.services.<service_id>.id, job.services.<service_id>.ports). Service containers must be defined at the job level, but a composite action's steps can reference them via the job context.
Applied to files:
.github/workflows/run-ci-cd.yaml
📚 Learning: 2025-10-26T12:50:50.512Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 2429
File: backend/Makefile:30-32
Timestamp: 2025-10-26T12:50:50.512Z
Learning: The `exec-backend-e2e-command` and `exec-db-e2e-command` Makefile targets in the backend/Makefile are intended for local development and debugging only, not for CI/CD execution, so the `-it` flags are appropriate.
Applied to files:
backend/Makefile
📚 Learning: 2025-08-31T13:48:09.830Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2155
File: frontend/graphql-codegen.ts:0-0
Timestamp: 2025-08-31T13:48:09.830Z
Learning: In the OWASP/Nest project, Django's GraphQL endpoint accepts CSRF tokens via 'x-csrftoken' header (lowercase) without requiring a Referer header, working fine in their configuration for GraphQL codegen introspection.
Applied to files:
backend/docker/fuzz/tests/test_graphql.py
📚 Learning: 2025-12-31T05:17:39.659Z
Learnt from: kart-u
Repo: OWASP/Nest PR: 3101
File: backend/apps/common/extensions.py:92-98
Timestamp: 2025-12-31T05:17:39.659Z
Learning: In this codebase, import OperationType for GraphQL operations from the graphql-core package rather than from strawberry. Use 'from graphql import OperationType'. Strawberry re-exports via graphql-core internally, so relying on strawberry's API may be brittle. Apply this rule to all Python files that deal with GraphQL operation types; ensure imports come from graphql (graphql-core) and not from strawberry packages. This improves compatibility and avoids coupling to strawberry's internals.
Applied to files:
backend/docker/fuzz/tests/test_graphql.pybackend/docker/fuzz/tests/test_rest.py
📚 Learning: 2025-12-26T06:57:19.911Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:19.911Z
Learning: In docker-compose/fuzz.yaml, document and enforce that the data-loader and graphql services are started in separate phases as defined by the Makefile target test-fuzz: first load data to completion, then start the graphql fuzzer against the populated database. Do not rely on orchestration order from docker-compose dependencies; instead ensure the Makefile orchestrates the phased startup and that health checks reflect runtime readiness rather than enforcing a start order. This guideline is specific to this file and to the fuzz testing setup in the OWASP/Nest repository.
Applied to files:
docker-compose/fuzz.yaml
📚 Learning: 2025-12-26T06:08:58.549Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 3041
File: .github/workflows/run-ci-cd.yaml:233-243
Timestamp: 2025-12-26T06:08:58.549Z
Learning: Ensure Redis image versions stay in sync across all environments by updating every relevant YAML file together (docker-compose files and CI/CD workflow configurations). When upgrading Redis, bump the image version in all docker-compose files and in all CI workflow YAMLs in one coordinated change to maintain parity across production, staging, local, E2E, and CI tests.
Applied to files:
docker-compose/fuzz.yaml
🪛 Shellcheck (0.11.0)
backend/docker/fuzz/entrypoint.sh
[warning] 11-11: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 11-11: Quote this to prevent word splitting.
(SC2046)
⏰ 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). (4)
- GitHub Check: Run fuzz tests
- GitHub Check: Run frontend unit tests
- GitHub Check: Run frontend e2e tests
- GitHub Check: Run backend tests
🔇 Additional comments (9)
backend/Makefile (1)
173-173: LGTM! REST fuzz service added to orchestration.The addition of the
restservice to the fuzz test orchestration aligns with the broader migration to schemathesis and the introduction of REST API fuzzing.Based on learnings, the Makefile orchestrates fuzz services in phases: data-loader completes first, then graphql and rest fuzzers run against the populated database.
backend/docker/fuzz/tests/test_rest.py (1)
7-13: Verify CSRF_TOKEN is set before use.Similar to test_graphql.py, the
CSRF_TOKENcould beNoneif the environment variable is not set. While the entrypoint validates this, defensive checks here improve robustness..github/workflows/run-ci-cd.yaml (2)
374-374: LGTM! Dockerfile path updated correctly.The fuzz Dockerfile path now correctly points to the new location
backend/docker/fuzz/Dockerfile, aligning with the restructured fuzz testing infrastructure.
379-388: LGTM! Fuzz tests now run separately for GraphQL and REST.The workflow correctly runs GraphQL and REST fuzz tests as separate steps, each with their own
TEST_FILEparameter. The REST test appropriately includes theREST_URLparameter for the OpenAPI schema endpoint.The simplified execution model (removed volume mounting and results upload) makes the workflow more straightforward.
backend/docker/fuzz/Dockerfile (3)
15-15: LGTM! Build dependencies optimized for schemathesis.The removal of build tools (
gcc,musl-dev,libffi-dev,openblas) and the switch fromgraphqlertoschemathesisis appropriate. Schemathesis is a pure Python package that doesn't require native compilation, resulting in a smaller, faster-building image.Also applies to: 21-21
25-26: LGTM! Entrypoint and tests correctly copied.The updated COPY commands correctly reference the renamed
entrypoint.shand add thetestsdirectory to the image, with appropriate permissions and ownership.
1-1: No action required. Schemathesis has official support for Python 3.13 as of v3.38.0, and recent releases are built with CPython 3.13.7 wheels.docker-compose/fuzz.yaml (2)
70-84: LGTM! GraphQL fuzz service updated correctly.The graphql service has been properly updated to use the new
nest-fuzzimage with the restructured build context, environment-driven test file selection viaTEST_FILE, and integration with thefuzz-nest-network. The removal of volumes simplifies the configuration.
85-98: Reconsider the REST service's dependency on the GraphQL service.The
restservice declares a dependency ongraphqlwithcondition: service_started. Based on the project's architecture where the Makefile orchestrates fuzz tests in separate phases rather than running them simultaneously, this docker-compose dependency may be unnecessary. If the REST and GraphQL fuzz tests are independent and executed sequentially by the Makefile (not concurrently via docker-compose), this dependency does not serve its apparent purpose—service_startedonly confirms the container is running, not that fuzzing has completed.Verify that the REST test actually requires GraphQL to be running. If the tests are independent, remove this dependency.
There was a problem hiding this comment.
Actionable comments posted: 5
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
.github/workflows/run-ci-cd.yaml.github/workflows/run-fuzz-tests.yamlbackend/Makefilebackend/apps/api/rest/v0/__init__.pybackend/apps/owasp/models/project_health_metrics.pybackend/docker/fuzz/Dockerfilebackend/docker/fuzz/entrypoint.shbackend/docker/fuzz/tests/test_graphql.pydocker-compose/fuzz.yaml
🚧 Files skipped from review as they are similar to previous changes (3)
- docker-compose/fuzz.yaml
- backend/docker/fuzz/entrypoint.sh
- backend/Makefile
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
📚 Learning: 2025-12-26T06:57:30.908Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Applied to files:
backend/docker/fuzz/Dockerfile.github/workflows/run-fuzz-tests.yamlbackend/docker/fuzz/tests/test_graphql.py.github/workflows/run-ci-cd.yaml
📚 Learning: 2025-12-21T19:03:59.068Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: .github/workflows/setup-backend-environment/action.yaml:16-27
Timestamp: 2025-12-21T19:03:59.068Z
Learning: Composite actions (runs: using: composite) execute as steps within the calling job's context and can access the job context, including job.services.* properties (e.g., job.services.<service_id>.id, job.services.<service_id>.ports). Service containers must be defined at the job level, but a composite action's steps can reference them via the job context.
Applied to files:
.github/workflows/run-fuzz-tests.yaml.github/workflows/run-ci-cd.yaml
📚 Learning: 2025-08-31T13:48:09.830Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2155
File: frontend/graphql-codegen.ts:0-0
Timestamp: 2025-08-31T13:48:09.830Z
Learning: In the OWASP/Nest project, Django's GraphQL endpoint accepts CSRF tokens via 'x-csrftoken' header (lowercase) without requiring a Referer header, working fine in their configuration for GraphQL codegen introspection.
Applied to files:
backend/docker/fuzz/tests/test_graphql.py
📚 Learning: 2025-12-31T05:17:39.659Z
Learnt from: kart-u
Repo: OWASP/Nest PR: 3101
File: backend/apps/common/extensions.py:92-98
Timestamp: 2025-12-31T05:17:39.659Z
Learning: In this codebase, import OperationType for GraphQL operations from the graphql-core package rather than from strawberry. Use 'from graphql import OperationType'. Strawberry re-exports via graphql-core internally, so relying on strawberry's API may be brittle. Apply this rule to all Python files that deal with GraphQL operation types; ensure imports come from graphql (graphql-core) and not from strawberry packages. This improves compatibility and avoids coupling to strawberry's internals.
Applied to files:
backend/docker/fuzz/tests/test_graphql.pybackend/apps/api/rest/v0/__init__.pybackend/apps/owasp/models/project_health_metrics.py
📚 Learning: 2025-08-04T15:55:08.017Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1967
File: backend/apps/owasp/api/internal/filters/project_health_metrics.py:24-27
Timestamp: 2025-08-04T15:55:08.017Z
Learning: In the OWASP Nest project, the `is_active` filter in `ProjectHealthMetricsFilter` is intentionally designed as a workaround to eliminate inactive projects from the dashboard. It only filters FOR active projects when `value=True`, and returns an empty Q() when `value=False` to avoid showing inactive projects. This is not meant to be a general boolean filter but a specific solution to exclude inactive projects from the project health metrics dashboard.
Applied to files:
backend/apps/owasp/models/project_health_metrics.py
🧬 Code graph analysis (1)
backend/apps/owasp/models/project_health_metrics.py (2)
backend/apps/owasp/api/internal/nodes/project_health_stats.py (1)
ProjectHealthStatsNode(7-21)frontend/src/types/__generated__/graphql.ts (1)
ProjectHealthStatsNode(593-607)
🪛 actionlint (1.7.9)
.github/workflows/run-fuzz-tests.yaml
17-17: "runs-on" section is missing in job "run-fuzz-tests"
(syntax-check)
92-92: property "base-url" is not defined in object type {rest-url: string; test-file: string}
(expression)
.github/workflows/run-ci-cd.yaml
308-308: when a reusable workflow is called with "uses", "timeout-minutes" is not available. only following keys are allowed: "name", "uses", "with", "secrets", "needs", "if", and "permissions" in job "run-graphql-fuzz-tests"
(syntax-check)
320-320: when a reusable workflow is called with "uses", "timeout-minutes" is not available. only following keys are allowed: "name", "uses", "with", "secrets", "needs", "if", and "permissions" in job "run-rest-fuzz-tests"
(syntax-check)
🔇 Additional comments (6)
backend/apps/owasp/models/project_health_metrics.py (2)
173-178: LGTM! Clean refactor using PostgreSQL's DISTINCT ON.The
order_by("project_id", "-nest_created_at").distinct("project_id")pattern correctly retrieves the latest metrics per project. The addition ofselect_related("project")optimizes related object fetching.
188-209: Good consolidation of aggregations with safe defaults.The single aggregate query with
Coalescefor default values is a clean approach that reduces database round-trips and handles empty result sets gracefully.backend/apps/api/rest/v0/__init__.py (1)
72-82: LGTM! Fuzz environment configuration follows existing patterns.The FUZZ environment configuration correctly mirrors the E2E and LOCAL environments by disabling authentication and throttling, which is appropriate for fuzz testing scenarios.
backend/docker/fuzz/tests/test_graphql.py (1)
1-21: LGTM! GraphQL fuzz test implementation is correct.The test properly:
- Loads the GraphQL schema with appropriate timeout settings
- Handles CSRF tokens as required by Django (both header and cookie)
- Uses schemathesis parametrization for comprehensive API fuzzing
backend/docker/fuzz/Dockerfile (2)
16-16: Nice optimization: Removed unnecessary build dependencies.The removal of gcc, musl-dev, libffi-dev, and openblas is appropriate since schemathesis is pure Python and doesn't require compilation. This reduces the image size and attack surface.
1-1: No action needed. Python 3.13.7 is a valid released version, and schemathesis 4.7.9 is compatible with Python 3.13 (requires >=3.10).
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
.github/workflows/run-fuzz-tests.yaml (2)
90-96: Duplicate: Reference to undefined workflow inputbase-url.Line 94 references
inputs.base-url, but this input is not defined in the workflow's inputs section (lines 5-14). This issue has been flagged in previous review comments and must be resolved by adding thebase-urlinput definition.
5-14: Critical: Missing requiredbase-urlinput definition.The workflow references
inputs.base-urlat line 94, butbase-urlis not defined in the inputs section. Both calling jobs in.github/workflows/run-ci-cd.yaml(lines 310 and 321) attempt to pass this input, which will be silently ignored, resulting in an emptyBASE_URLenvironment variable and likely test failures.🔎 Proposed fix
inputs: test-file: description: 'The test file to run fuzz tests on' required: true type: string rest-url: description: 'The REST API URL to test against' required: false type: string default: '' + base-url: + description: 'The base URL for the backend service' + required: true + type: string
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.github/workflows/run-ci-cd.yaml.github/workflows/run-fuzz-tests.yaml
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
📚 Learning: 2025-12-26T06:57:30.908Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Applied to files:
.github/workflows/run-ci-cd.yaml.github/workflows/run-fuzz-tests.yaml
📚 Learning: 2025-12-21T19:03:59.068Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: .github/workflows/setup-backend-environment/action.yaml:16-27
Timestamp: 2025-12-21T19:03:59.068Z
Learning: Composite actions (runs: using: composite) execute as steps within the calling job's context and can access the job context, including job.services.* properties (e.g., job.services.<service_id>.id, job.services.<service_id>.ports). Service containers must be defined at the job level, but a composite action's steps can reference them via the job context.
Applied to files:
.github/workflows/run-ci-cd.yaml.github/workflows/run-fuzz-tests.yaml
🪛 actionlint (1.7.9)
.github/workflows/run-ci-cd.yaml
310-310: input "base-url" is not defined in "./.github/workflows/run-fuzz-tests.yaml" reusable workflow. defined inputs are "rest-url", "test-file"
(workflow-call)
321-321: input "base-url" is not defined in "./.github/workflows/run-fuzz-tests.yaml" reusable workflow. defined inputs are "rest-url", "test-file"
(workflow-call)
.github/workflows/run-fuzz-tests.yaml
94-94: property "base-url" is not defined in object type {rest-url: string; test-file: string}
(expression)
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.github/workflows/run-fuzz-tests.yaml (1)
90-95: Consider making BASE_URL configurable via workflow input.Line 95 hardcodes
BASE_URLtohttp://localhost:9500. While this works for the current setup, making it an optional input parameter would improve workflow reusability and allow testing against different backend configurations without modifying the workflow.🔎 Proposed enhancement
Add a
base-urlinput to the workflow:inputs: test-file: description: 'The test file to run fuzz tests on' required: true type: string rest-url: description: 'The REST API URL to test against' required: false type: string default: '' + base-url: + description: 'The base URL for the backend service' + required: false + type: string + default: 'http://localhost:9500'Then update line 95:
- docker run -e BASE_URL=http://localhost:9500 -e TEST_FILE="$TEST_FILE" -e REST_URL="$REST_URL" --network host owasp/nest:test-fuzz-backend-latest + docker run -e BASE_URL="${{ inputs.base-url }}" -e TEST_FILE="$TEST_FILE" -e REST_URL="$REST_URL" --network host owasp/nest:test-fuzz-backend-latest
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.github/workflows/run-ci-cd.yaml.github/workflows/run-fuzz-tests.yaml
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
📚 Learning: 2025-12-26T06:57:30.908Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Applied to files:
.github/workflows/run-ci-cd.yaml.github/workflows/run-fuzz-tests.yaml
📚 Learning: 2025-12-21T19:03:59.068Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: .github/workflows/setup-backend-environment/action.yaml:16-27
Timestamp: 2025-12-21T19:03:59.068Z
Learning: Composite actions (runs: using: composite) execute as steps within the calling job's context and can access the job context, including job.services.* properties (e.g., job.services.<service_id>.id, job.services.<service_id>.ports). Service containers must be defined at the job level, but a composite action's steps can reference them via the job context.
Applied to files:
.github/workflows/run-ci-cd.yaml.github/workflows/run-fuzz-tests.yaml
⏰ 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). (6)
- GitHub Check: Run REST fuzz tests / run-fuzz-tests
- GitHub Check: Run GraphQL fuzz tests / run-fuzz-tests
- GitHub Check: Run frontend e2e tests
- GitHub Check: Run backend tests
- GitHub Check: Run frontend unit tests
- GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (1)
.github/workflows/run-ci-cd.yaml (1)
302-319: LGTM! Fuzz test jobs properly delegate to the reusable workflow.The job definitions correctly split GraphQL and REST fuzz testing into separate jobs, each calling the shared workflow with appropriate inputs. The GraphQL test passes only
test-file, while the REST test additionally providesrest-urlfor endpoint-specific testing.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
backend/apps/owasp/models/project_health_metrics.py (2)
244-246: Redundant.get()calls with default values.Lines 244-246 use
stats.get("key", 0), butCoalescein the aggregate (lines 206-208) already guarantees non-None values. Use direct dictionary access (stats["key"]) for consistency with other stats accesses in the same return statement.
210-210: Critical: Division by zero safeguard not applied consistently.A safeguard was added on Line 210 (
or 1), but it's only used on Line 243. Lines 237 and 241 still directly usestats["projects_count_total"], which will raiseZeroDivisionErrorif no active projects exist.🔎 Proposed fix to apply safeguard consistently
total = stats["projects_count_total"] or 1 # Avoid division by zero monthly_overall_metrics = ( ProjectHealthMetrics.objects.annotate(month=ExtractMonth("nest_created_at")) .filter( nest_created_at__gte=timezone.now() - timezone.timedelta(days=365) ) # Last year data .order_by("month") .values("month") .distinct() .annotate( score=models.Avg("score"), ) ) months = [] scores = [] for entry in monthly_overall_metrics: months.append(entry["month"]) scores.append(entry["score"]) return ProjectHealthStatsNode( average_score=stats["average_score"], # We use all metrics instead of latest metrics to get the monthly trend monthly_overall_scores=scores, monthly_overall_scores_months=months, projects_count_healthy=stats["projects_count_healthy"], projects_count_need_attention=stats["projects_count_need_attention"], projects_count_unhealthy=stats["projects_count_unhealthy"], - projects_percentage_healthy=( - stats["projects_count_healthy"] / stats["projects_count_total"] - ) - * 100, + projects_percentage_healthy=(stats["projects_count_healthy"] / total) * 100, projects_percentage_need_attention=( - (stats["projects_count_need_attention"] / stats["projects_count_total"]) * 100 + (stats["projects_count_need_attention"] / total) * 100 ), projects_percentage_unhealthy=(stats["projects_count_unhealthy"] / total) * 100, - total_contributors=(stats.get("total_contributors", 0)), - total_forks=(stats.get("total_forks", 0)), - total_stars=(stats.get("total_stars", 0)), + total_contributors=stats["total_contributors"], + total_forks=stats["total_forks"], + total_stars=stats["total_stars"], )Also applies to: 236-243
🧹 Nitpick comments (1)
.github/workflows/run-fuzz-tests.yaml (1)
76-95: Refactor the docker run command for better readability.The fuzz image build configuration is excellent with appropriate caching. However, line 95's docker run command is very long and hard to read. Consider using line continuation for better maintainability.
🔎 Proposed fix
- name: Run fuzz tests env: TEST_FILE: ${{ inputs.test-file }} REST_URL: ${{ inputs.rest-url }} run: | - docker run -e BASE_URL=http://localhost:9500 -e TEST_FILE="$TEST_FILE" -e REST_URL="$REST_URL" --network host owasp/nest:test-fuzz-backend-latest + docker run \ + -e BASE_URL=http://localhost:9500 \ + -e TEST_FILE="$TEST_FILE" \ + -e REST_URL="$REST_URL" \ + --network host \ + owasp/nest:test-fuzz-backend-latestAdditionally, consider adding a cleanup step to stop the backend container, especially if fuzz tests fail:
🔎 Optional cleanup step
Add this step at the end of the job:
- name: Stop backend container if: always() run: | docker stop fuzz-nest-backend || true
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
.github/workflows/run-fuzz-tests.yamlbackend/apps/owasp/models/project_health_metrics.pybackend/docker/fuzz/entrypoint.sh
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
📚 Learning: 2025-12-26T06:57:30.908Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Applied to files:
backend/docker/fuzz/entrypoint.sh.github/workflows/run-fuzz-tests.yaml
📚 Learning: 2025-08-04T15:55:08.017Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1967
File: backend/apps/owasp/api/internal/filters/project_health_metrics.py:24-27
Timestamp: 2025-08-04T15:55:08.017Z
Learning: In the OWASP Nest project, the `is_active` filter in `ProjectHealthMetricsFilter` is intentionally designed as a workaround to eliminate inactive projects from the dashboard. It only filters FOR active projects when `value=True`, and returns an empty Q() when `value=False` to avoid showing inactive projects. This is not meant to be a general boolean filter but a specific solution to exclude inactive projects from the project health metrics dashboard.
Applied to files:
backend/apps/owasp/models/project_health_metrics.py
📚 Learning: 2025-06-21T12:22:01.889Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/GradientRadialChart.tsx:113-113
Timestamp: 2025-06-21T12:22:01.889Z
Learning: In the OWASP Nest project, health metrics requirements (like lastCommitDaysRequirement, lastReleaseDaysRequirement) should never be 0. A requirement value of 0 is considered invalid and should result in displaying 0 on the radial chart.
Applied to files:
backend/apps/owasp/models/project_health_metrics.py
📚 Learning: 2025-12-31T05:17:39.659Z
Learnt from: kart-u
Repo: OWASP/Nest PR: 3101
File: backend/apps/common/extensions.py:92-98
Timestamp: 2025-12-31T05:17:39.659Z
Learning: In this codebase, import OperationType for GraphQL operations from the graphql-core package rather than from strawberry. Use 'from graphql import OperationType'. Strawberry re-exports via graphql-core internally, so relying on strawberry's API may be brittle. Apply this rule to all Python files that deal with GraphQL operation types; ensure imports come from graphql (graphql-core) and not from strawberry packages. This improves compatibility and avoids coupling to strawberry's internals.
Applied to files:
backend/apps/owasp/models/project_health_metrics.py
📚 Learning: 2025-12-21T19:03:59.068Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: .github/workflows/setup-backend-environment/action.yaml:16-27
Timestamp: 2025-12-21T19:03:59.068Z
Learning: Composite actions (runs: using: composite) execute as steps within the calling job's context and can access the job context, including job.services.* properties (e.g., job.services.<service_id>.id, job.services.<service_id>.ports). Service containers must be defined at the job level, but a composite action's steps can reference them via the job context.
Applied to files:
.github/workflows/run-fuzz-tests.yaml
🧬 Code graph analysis (1)
backend/apps/owasp/models/project_health_metrics.py (2)
backend/apps/owasp/api/internal/nodes/project_health_stats.py (1)
ProjectHealthStatsNode(7-21)frontend/src/types/__generated__/graphql.ts (1)
ProjectHealthStatsNode(593-607)
⏰ 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). (6)
- GitHub Check: Run REST fuzz tests / run-fuzz-tests
- GitHub Check: Run GraphQL fuzz tests / run-fuzz-tests
- GitHub Check: Run frontend unit tests
- GitHub Check: Run frontend e2e tests
- GitHub Check: Run backend tests
- GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (13)
backend/apps/owasp/models/project_health_metrics.py (4)
7-7: LGTM!The new imports (
Coalesce,ExtractMonth) are properly utilized in the refactored aggregation logic and monthly metrics computation.
173-178: Efficient refactor using database-level distinct.The refactored query is cleaner and more efficient than a subquery approach. The use of
select_related("project")prevents N+1 queries, anddistinct("project_id")with proper ordering ensures the latest metric per project is selected.Note:
distinct("project_id")is PostgreSQL-specific, but this appears to be acceptable for this project.
188-209: Excellent refactor to database-level aggregation.The new implementation leverages Django's ORM aggregation with
Countfilters andCoalescefor safe defaults, which is significantly more efficient than iterating in Python. This is a best-practice approach for computing statistics.
223-227: LGTM!The explicit list construction for months and scores is clear and correct.
backend/docker/fuzz/entrypoint.sh (3)
1-8: LGTM!The error handling setup and BASE_URL validation are correct. Using
set -eensures the script aborts on errors, and the validation provides a clear error message when BASE_URL is missing.
10-16: LGTM!The CSRF token fetch and validation logic is correct. The previous concern about combining
exportwith command substitution has been addressed by splitting the assignment and export. The validation check ensures the token is neither empty nor null before proceeding.
21-26: LGTM!The schemathesis configuration file creation is correct. The
:>command truncates/creates the file, and the setting with 250 examples is appropriate for fuzz testing. The comment referencing the documentation is helpful..github/workflows/run-fuzz-tests.yaml (6)
1-14: LGTM!The workflow definition and inputs are well-structured. The
test-fileinput is required and enables parameterized test execution, whilerest-urlis optional with a sensible default. This reusable workflow design supports both GraphQL and REST fuzz testing scenarios.
16-33: Consider whether the 15-minute timeout is sufficient for fuzz testing.The job configuration is correct with appropriate service setup and health checks. However, with 250 examples per endpoint (as configured in entrypoint.sh), fuzz tests might take considerable time. Verify that 15 minutes is sufficient for the expected test load, or consider increasing it to prevent premature termination of valid test runs.
34-46: LGTM!The setup steps are correct. Using pinned commit SHAs for GitHub Actions is a security best practice. The backend environment setup action is properly configured with fuzz-specific database credentials that match the service container configuration.
47-58: LGTM!The backend container configuration is appropriate for fuzz testing. Using host networking enables the fuzz container to access the backend via localhost:9500, and the migration + gunicorn startup sequence ensures the database schema is ready before tests run.
60-68: LGTM!The readiness check correctly uses a timeout to prevent indefinite waiting and polls the backend with appropriate intervals. The step will fail if the backend doesn't become ready within 5 minutes, which is the desired behavior.
70-74: LGTM!The data loading step is configured correctly with appropriate credentials and uses the PGPASSWORD environment variable for secure authentication. The restore from
backend/data/nest.dumpprovides the initial dataset for fuzz testing.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
backend/apps/owasp/models/project_health_metrics.py (2)
210-210: Consider more explicit zero-division handling.While
or 1technically prevents division by zero, the explicit conditional approach suggested in the prior review is clearer and more maintainable.🔎 Recommended refactor for explicit safety
- total = stats["projects_count_total"] or 1 # Avoid division by zero + total = stats["projects_count_total"] monthly_overall_metrics = ( ProjectHealthMetrics.objects.annotate(month=ExtractMonth("nest_created_at")) .filter( nest_created_at__gte=timezone.now() - timezone.timedelta(days=365) ) # Last year data .order_by("month") .values("month") .distinct() .annotate( score=models.Avg("score"), ) ) months = [] scores = [] for entry in monthly_overall_metrics: months.append(entry["month"]) scores.append(entry["score"]) return ProjectHealthStatsNode( average_score=stats["average_score"], # We use all metrics instead of latest metrics to get the monthly trend monthly_overall_scores=scores, monthly_overall_scores_months=months, projects_count_healthy=stats["projects_count_healthy"], projects_count_need_attention=stats["projects_count_need_attention"], projects_count_unhealthy=stats["projects_count_unhealthy"], projects_percentage_healthy=( - stats["projects_count_healthy"] / total - ) - * 100, + stats["projects_count_healthy"] / total * 100 if total > 0 else 0.0 + ), projects_percentage_need_attention=( - (stats["projects_count_need_attention"] / total) * 100 + stats["projects_count_need_attention"] / total * 100 if total > 0 else 0.0 ), - projects_percentage_unhealthy=(stats["projects_count_unhealthy"] / total) * 100, + projects_percentage_unhealthy=( + stats["projects_count_unhealthy"] / total * 100 if total > 0 else 0.0 + ),Note: This also addresses the ruff-format pipeline failure.
Also applies to: 236-243
244-246: Remove redundant parentheses for consistency.The parentheses around
stats["total_contributors"],stats["total_forks"], andstats["total_stars"]are unnecessary and inconsistent with line 229.🔎 Cleanup suggestion
- total_contributors=(stats["total_contributors"]), - total_forks=(stats["total_forks"]), - total_stars=(stats["total_stars"]), + total_contributors=stats["total_contributors"], + total_forks=stats["total_forks"], + total_stars=stats["total_stars"],backend/docker/fuzz/entrypoint.sh (1)
35-36: Consider quoting the test path for shell best practices.The pytest command correctly uses the TEST_FILE variable. As a minor shell scripting best practice, consider quoting the path to handle edge cases:
🔎 Optional improvement
echo "Starting fuzzing process..." -pytest -s ./tests/${TEST_FILE} +pytest -s "./tests/${TEST_FILE}"Note: This is a minor defensive coding suggestion—TEST_FILE is unlikely to contain spaces in practice given it's set by docker-compose configuration.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
backend/apps/owasp/models/project_health_metrics.pybackend/docker/fuzz/entrypoint.sh
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
📚 Learning: 2025-08-04T15:55:08.017Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1967
File: backend/apps/owasp/api/internal/filters/project_health_metrics.py:24-27
Timestamp: 2025-08-04T15:55:08.017Z
Learning: In the OWASP Nest project, the `is_active` filter in `ProjectHealthMetricsFilter` is intentionally designed as a workaround to eliminate inactive projects from the dashboard. It only filters FOR active projects when `value=True`, and returns an empty Q() when `value=False` to avoid showing inactive projects. This is not meant to be a general boolean filter but a specific solution to exclude inactive projects from the project health metrics dashboard.
Applied to files:
backend/apps/owasp/models/project_health_metrics.py
📚 Learning: 2025-06-21T12:22:01.889Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/GradientRadialChart.tsx:113-113
Timestamp: 2025-06-21T12:22:01.889Z
Learning: In the OWASP Nest project, health metrics requirements (like lastCommitDaysRequirement, lastReleaseDaysRequirement) should never be 0. A requirement value of 0 is considered invalid and should result in displaying 0 on the radial chart.
Applied to files:
backend/apps/owasp/models/project_health_metrics.py
📚 Learning: 2025-12-31T05:17:39.659Z
Learnt from: kart-u
Repo: OWASP/Nest PR: 3101
File: backend/apps/common/extensions.py:92-98
Timestamp: 2025-12-31T05:17:39.659Z
Learning: In this codebase, import OperationType for GraphQL operations from the graphql-core package rather than from strawberry. Use 'from graphql import OperationType'. Strawberry re-exports via graphql-core internally, so relying on strawberry's API may be brittle. Apply this rule to all Python files that deal with GraphQL operation types; ensure imports come from graphql (graphql-core) and not from strawberry packages. This improves compatibility and avoids coupling to strawberry's internals.
Applied to files:
backend/apps/owasp/models/project_health_metrics.py
📚 Learning: 2025-12-26T06:57:30.908Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Applied to files:
backend/docker/fuzz/entrypoint.sh
📚 Learning: 2025-06-18T20:00:23.899Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1634
File: frontend/src/app/api/auth/[...nextauth]/route.ts:30-55
Timestamp: 2025-06-18T20:00:23.899Z
Learning: The OWASP Nest application has logging disabled, so avoid suggesting console.log, console.error, or any other logging statements in code review suggestions.
Applied to files:
backend/docker/fuzz/entrypoint.sh
🪛 GitHub Actions: Run CI/CD
backend/apps/owasp/models/project_health_metrics.py
[error] 233-239: pre-commit: ruff-format reformatted 1 file; formatting changes were applied and caused the hook to fail. Re-run pre-commit to verify (e.g., 'pre-commit run --all-files') or run 'ruff format' to fix formatting.
⏰ 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: CodeQL (javascript-typescript)
🔇 Additional comments (8)
backend/apps/owasp/models/project_health_metrics.py (3)
7-7: LGTM: Coalesce import supports safe aggregation.The addition of
Coalesceis appropriate for handling NULL values in the aggregation logic below.
173-178: Excellent query optimization.The refactored query efficiently retrieves the latest metrics per project using
select_related, proper ordering, anddistinct, eliminating the need for subqueries.
188-209: Well-structured aggregation with safe defaults.The consolidated aggregate query with
Coalesceand conditional counts is efficient and ensures safe handling of NULL values.backend/docker/fuzz/entrypoint.sh (5)
1-3: LGTM!The POSIX shebang and
set -eprovide good portability and error handling for the fuzzing entrypoint.
5-8: LGTM!The BASE_URL validation provides clear error feedback and proper exit handling.
10-20: Excellent fixes addressing previous security and correctness concerns!The CSRF token retrieval and validation now properly handles:
- Command substitution separated from export (line 11, 18) - preventing exit code masking ✓
- Logging confirms success without exposing the token value (line 20) - addressing security concern ✓
- Comprehensive validation for empty/null tokens (lines 13-16)
21-26: LGTM!The schemathesis configuration is clearly documented and the 250 examples limit is reasonable for fuzzing.
28-33: Great addition of TEST_FILE validation!The validation logic addresses the previous review feedback by ensuring TEST_FILE is set before attempting to run pytest. Clear error handling and messaging.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @backend/apps/owasp/models/project.py:
- Around line 200-215: The select_related call on the Issue queryset contains a
duplicate entry for "repository" — find the code returning
Issue.objects.filter(...).select_related(...).prefetch_related(...) (the method
in the Project model that builds the issues queryset) and remove the redundant
"repository" string from the select_related list so each related field appears
only once while keeping the other relations ("author", "level", "milestone")
intact.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
backend/apps/owasp/models/project.py
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/snapshots/[id]/page.tsx:0-0
Timestamp: 2025-09-21T17:04:48.154Z
Learning: User rudransh-shrivastava confirmed that suggested type safety improvements during Apollo Client migration were no longer relevant, reinforcing their preference to keep migration PRs focused on core migration changes rather than additional improvements.
📚 Learning: 2025-08-04T15:55:08.017Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1967
File: backend/apps/owasp/api/internal/filters/project_health_metrics.py:24-27
Timestamp: 2025-08-04T15:55:08.017Z
Learning: In the OWASP Nest project, the `is_active` filter in `ProjectHealthMetricsFilter` is intentionally designed as a workaround to eliminate inactive projects from the dashboard. It only filters FOR active projects when `value=True`, and returns an empty Q() when `value=False` to avoid showing inactive projects. This is not meant to be a general boolean filter but a specific solution to exclude inactive projects from the project health metrics dashboard.
Applied to files:
backend/apps/owasp/models/project.py
📚 Learning: 2025-11-23T11:37:26.253Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2606
File: backend/apps/api/rest/v0/project.py:43-48
Timestamp: 2025-11-23T11:37:26.253Z
Learning: In the OWASP Nest backend, `entity_leaders` is a `property` method defined in `RepositoryBasedEntityModel` (backend/apps/owasp/models/common.py) that returns a dynamically constructed QuerySet. It cannot be prefetched using standard `prefetch_related()` because Django's prefetch mechanism only works on model fields and relations, not property methods.
Applied to files:
backend/apps/owasp/models/project.py
📚 Learning: 2026-01-06T12:38:23.460Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 3122
File: backend/apps/owasp/api/internal/nodes/project.py:52-61
Timestamp: 2026-01-06T12:38:23.460Z
Learning: In backend/apps/owasp/api/internal/nodes/project.py, the health_metrics_list method intentionally orders by nest_created_at ascending (oldest first) to return metrics in chronological order for trend analysis, which differs from health_metrics_latest that orders descending to get the most recent metric.
Applied to files:
backend/apps/owasp/models/project.py
📚 Learning: 2025-12-31T05:17:39.659Z
Learnt from: kart-u
Repo: OWASP/Nest PR: 3101
File: backend/apps/common/extensions.py:92-98
Timestamp: 2025-12-31T05:17:39.659Z
Learning: In this codebase, import OperationType for GraphQL operations from the graphql-core package rather than from strawberry. Use 'from graphql import OperationType'. Strawberry re-exports via graphql-core internally, so relying on strawberry's API may be brittle. Apply this rule to all Python files that deal with GraphQL operation types; ensure imports come from graphql (graphql-core) and not from strawberry packages. This improves compatibility and avoids coupling to strawberry's internals.
Applied to files:
backend/apps/owasp/models/project.py
📚 Learning: 2026-01-01T17:48:23.963Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2948
File: backend/apps/owasp/management/commands/owasp_generate_community_snapshot_video.py:41-47
Timestamp: 2026-01-01T17:48:23.963Z
Learning: In Django code, be aware that a QuerySet's boolean evaluation (e.g., if not queryset) runs a database query to determine emptiness. While it is technically valid to use the queryset in a boolean context, use queryset.exists() for existence checks to avoid unnecessary queries and improve performance. Applicable broadly to Python/Django files rather than just this specific path.
Applied to files:
backend/apps/owasp/models/project.py
📚 Learning: 2026-01-01T18:57:05.007Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2948
File: backend/apps/owasp/video.py:189-215
Timestamp: 2026-01-01T18:57:05.007Z
Learning: In the OWASP backend area, maintain the established pattern: when dealing with sponsors, include all entries from Sponsor.objects.all() (including NOT_SPONSOR) and perform in-memory sorting using the same criteria/pattern used by the GraphQL sponsor query implemented in backend/apps/owasp/api/internal/queries/sponsor.py. Apply this behavior consistently to files in backend/apps/owasp (not just video.py), and ensure code paths that render sponsor lists follow this in-code sorting approach rather than pre-filtering NOT_SPONSOR entries before sorting.
Applied to files:
backend/apps/owasp/models/project.py
🧬 Code graph analysis (1)
backend/apps/owasp/models/project.py (1)
backend/apps/owasp/models/project_health_metrics.py (1)
ProjectHealthMetrics(18-247)
⏰ 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). (5)
- GitHub Check: Run GraphQL fuzz tests / Run Fuzz Tests
- GitHub Check: Run REST fuzz tests / Run Fuzz Tests
- GitHub Check: Run frontend unit tests
- GitHub Check: Run backend tests
- GitHub Check: Run frontend e2e tests
🔇 Additional comments (6)
backend/apps/owasp/models/project.py (6)
10-10: LGTM!The imports are correctly added -
GinIndexandOpClassfor the new trigram indexes, andProjectHealthMetricsunderTYPE_CHECKINGfor the type hint onlast_health_metrics.Also applies to: 32-32
53-64: GinIndex definitions look correct.The trigram indexes are properly configured for PostgreSQL text search. One consideration:
The
project_name_gin_idxincludes acondition=models.Q(is_active=True)filter, butproject_leaders_raw_gin_idxdoes not. If leader search is also primarily used for active projects, adding a similar condition would reduce index size and maintenance overhead.
222-225: LGTM!The implementation correctly retrieves the latest health metrics using the
health_metricsrelated manager with proper ordering. The return type annotation accurately reflects thatfirst()may returnNone.
262-270: LGTM!The query optimization with
select_relatedandprefetch_relatedis well-structured for eager loading related data.
284-291: LGTM!The
select_relatedaddition appropriately optimizes fetching related author and repository data for published releases.
293-307: LGTM!The
recent_milestonesproperty follows the same optimization pattern used consistently across other properties in this model.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/run-ci-cd.yaml (1)
286-299: Fix environment variable name mismatch: useREDIS_AUTH_ENABLEDinstead ofDJANGO_REDIS_AUTH_ENABLEDThe backend settings read
REDIS_AUTH_ENABLED(without theDJANGO_prefix) on line 143 ofbackend/settings/base.py, but the workflow setsDJANGO_REDIS_AUTH_ENABLED=False. This mismatch means the settings will ignore the environment variable, defaultREDIS_AUTH_ENABLEDtoTrue, and attempt Redis authentication in CI—causing connection failures since no credentials are available.Change the workflow to:
-e REDIS_AUTH_ENABLED=FalseAlternatively, update
backend/settings/base.pyline 143 to readDJANGO_REDIS_AUTH_ENABLEDif that is the intended naming convention across the project. Ensure the.envfiles and workflow use consistent environment variable names.
🧹 Nitpick comments (1)
backend/Makefile (1)
124-126: Consider adding validation or documentation for the requiredAPP_NAMEvariable.If
APP_NAMEis not provided, the command expands tomakemigrations --emptywithout an app label, causing Django to fail with an unclear error. Either add a guard or document the required usage.Optional: Add a guard for missing APP_NAME
migrations-empty: +ifndef APP_NAME + $(error APP_NAME is required. Usage: make migrations-empty APP_NAME=<app_name>) +endif @CMD="python manage.py makemigrations --empty $(APP_NAME)" $(MAKE) exec-backend-command
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
.github/workflows/run-ci-cd.yamlbackend/.env.examplebackend/Makefilebackend/apps/github/models/organization.pycspell/custom-dict.txt
🚧 Files skipped from review as they are similar to previous changes (1)
- cspell/custom-dict.txt
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/snapshots/[id]/page.tsx:0-0
Timestamp: 2025-09-21T17:04:48.154Z
Learning: User rudransh-shrivastava confirmed that suggested type safety improvements during Apollo Client migration were no longer relevant, reinforcing their preference to keep migration PRs focused on core migration changes rather than additional improvements.
📚 Learning: 2025-12-26T06:57:30.908Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Applied to files:
.github/workflows/run-ci-cd.yamlbackend/Makefile
📚 Learning: 2025-12-26T06:09:08.868Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 3041
File: .github/workflows/run-ci-cd.yaml:233-243
Timestamp: 2025-12-26T06:09:08.868Z
Learning: For the OWASP/Nest repository, Redis image versions should remain consistent across all environments (production, staging, local, E2E, and CI/CD E2E tests). When upgrading Redis, update all docker-compose files and CI/CD workflow configurations together to maintain environment parity.
Applied to files:
.github/workflows/run-ci-cd.yamlbackend/Makefile
📚 Learning: 2025-12-21T19:03:59.068Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: .github/workflows/setup-backend-environment/action.yaml:16-27
Timestamp: 2025-12-21T19:03:59.068Z
Learning: Composite actions (runs: using: composite) execute as steps within the calling job's context and can access the job context, including job.services.* properties (e.g., job.services.<service_id>.id, job.services.<service_id>.ports). Service containers must be defined at the job level, but a composite action's steps can reference them via the job context.
Applied to files:
.github/workflows/run-ci-cd.yaml
📚 Learning: 2025-11-23T11:37:26.253Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2606
File: backend/apps/api/rest/v0/project.py:43-48
Timestamp: 2025-11-23T11:37:26.253Z
Learning: In the OWASP Nest backend, `entity_leaders` is a `property` method defined in `RepositoryBasedEntityModel` (backend/apps/owasp/models/common.py) that returns a dynamically constructed QuerySet. It cannot be prefetched using standard `prefetch_related()` because Django's prefetch mechanism only works on model fields and relations, not property methods.
Applied to files:
backend/apps/github/models/organization.py
📚 Learning: 2025-12-31T05:17:39.659Z
Learnt from: kart-u
Repo: OWASP/Nest PR: 3101
File: backend/apps/common/extensions.py:92-98
Timestamp: 2025-12-31T05:17:39.659Z
Learning: In this codebase, import OperationType for GraphQL operations from the graphql-core package rather than from strawberry. Use 'from graphql import OperationType'. Strawberry re-exports via graphql-core internally, so relying on strawberry's API may be brittle. Apply this rule to all Python files that deal with GraphQL operation types; ensure imports come from graphql (graphql-core) and not from strawberry packages. This improves compatibility and avoids coupling to strawberry's internals.
Applied to files:
backend/apps/github/models/organization.py
📚 Learning: 2026-01-01T17:48:23.963Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2948
File: backend/apps/owasp/management/commands/owasp_generate_community_snapshot_video.py:41-47
Timestamp: 2026-01-01T17:48:23.963Z
Learning: In Django code, be aware that a QuerySet's boolean evaluation (e.g., if not queryset) runs a database query to determine emptiness. While it is technically valid to use the queryset in a boolean context, use queryset.exists() for existence checks to avoid unnecessary queries and improve performance. Applicable broadly to Python/Django files rather than just this specific path.
Applied to files:
backend/apps/github/models/organization.py
📚 Learning: 2025-10-26T12:50:50.512Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 2429
File: backend/Makefile:30-32
Timestamp: 2025-10-26T12:50:50.512Z
Learning: The `exec-backend-e2e-command` and `exec-db-e2e-command` Makefile targets in the backend/Makefile are intended for local development and debugging only, not for CI/CD execution, so the `-it` flags are appropriate.
Applied to files:
backend/Makefile
📚 Learning: 2026-01-05T16:20:47.532Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 3205
File: docker-compose/local.yaml:32-32
Timestamp: 2026-01-05T16:20:47.532Z
Learning: In the OWASP/Nest repository, feature branches use unique volume name suffixes in docker-compose files to prevent volume clashes across parallel development efforts. For example, the feature/nest-zappa-migration branch uses `-zappa` suffix for all volume names (backend-venv-zappa, cache-data-zappa, db-data-zappa, etc.) to ensure isolated environments when switching between branches.
Applied to files:
backend/Makefile
🧬 Code graph analysis (1)
backend/apps/github/models/organization.py (1)
backend/tests/apps/owasp/management/commands/owasp_aggregate_contributions_test.py (3)
select_related(36-38)prefetch_related(40-42)filter(28-30)
⏰ 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). (7)
- GitHub Check: Run GraphQL fuzz tests / Run Fuzz Tests
- GitHub Check: Run backend tests
- GitHub Check: Run REST fuzz tests / Run Fuzz Tests
- GitHub Check: Run frontend unit tests
- GitHub Check: Run frontend e2e tests
- GitHub Check: Run frontend accessibility tests
- GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (5)
backend/apps/github/models/organization.py (1)
55-63: LGTM! Eager loading added torelated_projectsproperty.This change aligns with the PR objectives to move
select_related/prefetch_relatedoptimizations into resolver/property bodies rather than using GraphQL field decorator hints, which was causing Schemathesis to generate invalid queries due to schema pollution.The query chain ordering is correct—
select_relatedandprefetch_relatedare applied before the filter anddistinct(), which is valid Django ORM usage. All relations being optimized exist on the Project model:
owasp_repository: ForeignKey to "github.Repository"organizations,owners,repositories: ManyToManyFields to their respective modelsbackend/.env.example (1)
16-16: No action needed. The code is correct and follows the django-configurations library standards.Environment variable parsing is properly handled by
values.BooleanValue(), which automatically converts the string"True"to a boolean. The environment variable nameDJANGO_REDIS_AUTH_ENABLEDin the.envfiles is correct—the django-configurations library automatically prepends theDJANGO_prefix to allenviron_namevalues defined in settings. Consistency across.env.example,.env.e2e.example, and.env.fuzz.exampleis confirmed.Likely an incorrect or invalid review comment.
.github/workflows/run-ci-cd.yaml (2)
264-272: LGTM!The simplified health check (
redis-cli ping) is appropriate since CI Redis runs without authentication. This aligns with theDJANGO_REDIS_AUTH_ENABLED=Falseoverride for the backend container.
384-401: Good refactoring to a reusable workflow.Delegating both GraphQL and REST fuzz tests to a shared workflow reduces duplication and improves maintainability. The reusable workflow correctly defines the required
test-fileinput and optionalrest-urlinput (defaulting tohttp://localhost:9500/api/v0), matching the backend service port configuration. Both jobs use the workflow appropriately:run-graphql-fuzz-testspasses onlytest-file, whilerun-rest-fuzz-testspasses both parameters.backend/Makefile (1)
194-199: Addcacheservice to the REST fuzz step.The REST fuzz tests omit the
cacheservice while the GraphQL step includes it. Since the backend service explicitly depends on cache being healthy (as defined in docker-compose/fuzz/compose.yaml), this inconsistency will cause the backend to fail startup during REST tests. All REST API endpoints use the@cache_response()decorator, requiring Redis cache to function.Current Makefile diff (lines 194-199)
@echo "Running REST API fuzz tests..." @COMPOSE_BAKE=true DOCKER_BUILDKIT=1 \ docker compose --project-name nest-fuzz -f docker-compose/fuzz/compose.yaml up --build --remove-orphans --abort-on-container-exit db backend rest @echo "Running GraphQL fuzz tests..." @COMPOSE_BAKE=true DOCKER_BUILDKIT=1 \ docker compose --project-name nest-fuzz -f docker-compose/fuzz/compose.yaml up --build --remove-orphans --abort-on-container-exit db cache backend graphqlAdd
cacheto the REST step service list (line 196).⛔ Skipped due to learnings
Learnt from: ahmedxgouda Repo: OWASP/Nest PR: 1139 File: docker-compose/fuzz.yaml:70-83 Timestamp: 2025-12-26T06:57:30.908Z Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.Learnt from: ahmedxgouda Repo: OWASP/Nest PR: 3041 File: .github/workflows/run-ci-cd.yaml:233-243 Timestamp: 2025-12-26T06:09:08.868Z Learning: For the OWASP/Nest repository, Redis image versions should remain consistent across all environments (production, staging, local, E2E, and CI/CD E2E tests). When upgrading Redis, update all docker-compose files and CI/CD workflow configurations together to maintain environment parity.
304a53f to
349b72d
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @cspell/custom-dict.txt:
- Line 70: Remove the unused dictionary entry "euo" from cspell/custom-dict.txt:
open the file and delete the line containing the token euo so the custom
dictionary no longer contains an entry that isn't referenced anywhere in the
codebase.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
.github/workflows/run-ci-cd.yamlbackend/.env.examplebackend/Makefilebackend/apps/github/models/organization.pycspell/custom-dict.txt
🚧 Files skipped from review as they are similar to previous changes (2)
- backend/.env.example
- backend/Makefile
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/snapshots/[id]/page.tsx:0-0
Timestamp: 2025-09-21T17:04:48.154Z
Learning: User rudransh-shrivastava confirmed that suggested type safety improvements during Apollo Client migration were no longer relevant, reinforcing their preference to keep migration PRs focused on core migration changes rather than additional improvements.
📚 Learning: 2025-12-26T06:57:30.908Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Applied to files:
.github/workflows/run-ci-cd.yaml
📚 Learning: 2025-12-26T06:09:08.868Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 3041
File: .github/workflows/run-ci-cd.yaml:233-243
Timestamp: 2025-12-26T06:09:08.868Z
Learning: For the OWASP/Nest repository, Redis image versions should remain consistent across all environments (production, staging, local, E2E, and CI/CD E2E tests). When upgrading Redis, update all docker-compose files and CI/CD workflow configurations together to maintain environment parity.
Applied to files:
.github/workflows/run-ci-cd.yaml
📚 Learning: 2025-12-21T19:03:59.068Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: .github/workflows/setup-backend-environment/action.yaml:16-27
Timestamp: 2025-12-21T19:03:59.068Z
Learning: Composite actions (runs: using: composite) execute as steps within the calling job's context and can access the job context, including job.services.* properties (e.g., job.services.<service_id>.id, job.services.<service_id>.ports). Service containers must be defined at the job level, but a composite action's steps can reference them via the job context.
Applied to files:
.github/workflows/run-ci-cd.yaml
📚 Learning: 2025-11-23T11:37:26.253Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2606
File: backend/apps/api/rest/v0/project.py:43-48
Timestamp: 2025-11-23T11:37:26.253Z
Learning: In the OWASP Nest backend, `entity_leaders` is a `property` method defined in `RepositoryBasedEntityModel` (backend/apps/owasp/models/common.py) that returns a dynamically constructed QuerySet. It cannot be prefetched using standard `prefetch_related()` because Django's prefetch mechanism only works on model fields and relations, not property methods.
Applied to files:
backend/apps/github/models/organization.py
📚 Learning: 2025-12-31T05:17:39.659Z
Learnt from: kart-u
Repo: OWASP/Nest PR: 3101
File: backend/apps/common/extensions.py:92-98
Timestamp: 2025-12-31T05:17:39.659Z
Learning: In this codebase, import OperationType for GraphQL operations from the graphql-core package rather than from strawberry. Use 'from graphql import OperationType'. Strawberry re-exports via graphql-core internally, so relying on strawberry's API may be brittle. Apply this rule to all Python files that deal with GraphQL operation types; ensure imports come from graphql (graphql-core) and not from strawberry packages. This improves compatibility and avoids coupling to strawberry's internals.
Applied to files:
backend/apps/github/models/organization.py
📚 Learning: 2026-01-01T17:48:23.963Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2948
File: backend/apps/owasp/management/commands/owasp_generate_community_snapshot_video.py:41-47
Timestamp: 2026-01-01T17:48:23.963Z
Learning: In Django code, be aware that a QuerySet's boolean evaluation (e.g., if not queryset) runs a database query to determine emptiness. While it is technically valid to use the queryset in a boolean context, use queryset.exists() for existence checks to avoid unnecessary queries and improve performance. Applicable broadly to Python/Django files rather than just this specific path.
Applied to files:
backend/apps/github/models/organization.py
🧬 Code graph analysis (1)
backend/apps/github/models/organization.py (1)
backend/tests/apps/owasp/management/commands/owasp_aggregate_contributions_test.py (3)
select_related(36-38)prefetch_related(40-42)filter(28-30)
⏰ 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). (6)
- GitHub Check: Run REST fuzz tests / Run Fuzz Tests
- GitHub Check: Run GraphQL fuzz tests / Run Fuzz Tests
- GitHub Check: Run frontend accessibility tests
- GitHub Check: Run frontend unit tests
- GitHub Check: Run frontend e2e tests
- GitHub Check: Run backend tests
🔇 Additional comments (6)
cspell/custom-dict.txt (2)
146-146: LGTM!The addition of
schemathesisis well-justified given the PR's objective to migrate fuzz tests to the Schemathesis library. The entry is correctly placed in alphabetical order.
154-154: LGTM!The addition of
trgmis appropriate for the PostgreSQL trigram extension and GIN indexes mentioned in the summary. The entry is correctly placed in alphabetical order.backend/apps/github/models/organization.py (1)
55-63: [rewritten review comment]
[classification tag].github/workflows/run-ci-cd.yaml (3)
264-272: LGTM!The Redis health check change from
redis-cli -atoredis-cli pingis correct for the unauthenticated Redis setup in CI. Since the cache service doesn't setREDIS_PASSWORD, Redis runs without auth, andredis-cli pingis the appropriate health check.
286-299: LGTM!Adding
DJANGO_REDIS_HOST=localhostandDJANGO_REDIS_AUTH_ENABLED=Falsecorrectly addresses the Redis CI vs local mismatch. Since the Redis service container runs without authentication, disabling auth in Django ensures successful connections.
384-401: Clean refactor delegating fuzz tests to a shared workflow.The extraction of fuzz test orchestration into a reusable workflow (
.github/workflows/run-fuzz-tests.yaml) follows DRY principles well. The shared workflow correctly acceptstest-fileandrest-urlinputs, maintains phased orchestration (data load before fuzz execution), and both caller jobs properly configure their respective test parameters.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@backend/apps/owasp/api/internal/nodes/committee.py`:
- Around line 18-21: The created_at resolver for Committee uses
root.idx_created_at which can be None; update the resolver (def created_at(self,
root: Committee) -> float) to guard against null by returning None (or an
appropriate nullable type) when root.idx_created_at is None, otherwise return
the timestamp value; alternatively, implement the null check inside the
idx_created_at property to return None instead of calling .timestamp() on a None
value so that created_at no longer raises AttributeError.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
backend/apps/github/models/repository.pybackend/apps/owasp/api/internal/nodes/committee.py
🚧 Files skipped from review as they are similar to previous changes (1)
- backend/apps/github/models/repository.py
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/snapshots/[id]/page.tsx:0-0
Timestamp: 2025-09-21T17:04:48.154Z
Learning: User rudransh-shrivastava confirmed that suggested type safety improvements during Apollo Client migration were no longer relevant, reinforcing their preference to keep migration PRs focused on core migration changes rather than additional improvements.
📚 Learning: 2025-07-11T15:57:56.648Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: backend/apps/mentorship/graphql/queries/module.py:39-50
Timestamp: 2025-07-11T15:57:56.648Z
Learning: In the OWASP Nest mentorship GraphQL queries, Strawberry GraphQL automatically converts between Django Module instances and ModuleNode types, so methods can return Module instances directly without manual conversion even when typed as ModuleNode.
Applied to files:
backend/apps/owasp/api/internal/nodes/committee.py
📚 Learning: 2025-07-13T05:55:46.436Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: backend/apps/mentorship/graphql/mutations/program.py:166-166
Timestamp: 2025-07-13T05:55:46.436Z
Learning: In the OWASP Nest mentorship GraphQL mutations, Strawberry GraphQL automatically converts between Django Program instances and ProgramNode types, so mutations can return Program instances directly without manual conversion even when typed as ProgramNode, similar to the Module/ModuleNode pattern.
Applied to files:
backend/apps/owasp/api/internal/nodes/committee.py
📚 Learning: 2025-07-31T07:05:25.056Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 0
File: :0-0
Timestamp: 2025-07-31T07:05:25.056Z
Learning: In the OWASP Nest project, Django views may not properly access authenticated users from sessions created by Strawberry GraphQL mutations. The issue occurs because Django's AuthenticationMiddleware doesn't always populate request.user from session data that GraphQL context successfully uses via info.context.request.user. The solution is to manually resolve users from session data using request.session.get('_auth_user_id') and User.objects.select_related('github_user').get(pk=user_id) to match the same authentication mechanism used by GraphQL context.
Applied to files:
backend/apps/owasp/api/internal/nodes/committee.py
📚 Learning: 2025-12-31T05:17:39.659Z
Learnt from: kart-u
Repo: OWASP/Nest PR: 3101
File: backend/apps/common/extensions.py:92-98
Timestamp: 2025-12-31T05:17:39.659Z
Learning: In this codebase, import OperationType for GraphQL operations from the graphql-core package rather than from strawberry. Use 'from graphql import OperationType'. Strawberry re-exports via graphql-core internally, so relying on strawberry's API may be brittle. Apply this rule to all Python files that deal with GraphQL operation types; ensure imports come from graphql (graphql-core) and not from strawberry packages. This improves compatibility and avoids coupling to strawberry's internals.
Applied to files:
backend/apps/owasp/api/internal/nodes/committee.py
📚 Learning: 2026-01-01T17:48:23.963Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2948
File: backend/apps/owasp/management/commands/owasp_generate_community_snapshot_video.py:41-47
Timestamp: 2026-01-01T17:48:23.963Z
Learning: In Django code, be aware that a QuerySet's boolean evaluation (e.g., if not queryset) runs a database query to determine emptiness. While it is technically valid to use the queryset in a boolean context, use queryset.exists() for existence checks to avoid unnecessary queries and improve performance. Applicable broadly to Python/Django files rather than just this specific path.
Applied to files:
backend/apps/owasp/api/internal/nodes/committee.py
📚 Learning: 2026-01-01T18:57:05.007Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2948
File: backend/apps/owasp/video.py:189-215
Timestamp: 2026-01-01T18:57:05.007Z
Learning: In the OWASP backend area, maintain the established pattern: when dealing with sponsors, include all entries from Sponsor.objects.all() (including NOT_SPONSOR) and perform in-memory sorting using the same criteria/pattern used by the GraphQL sponsor query implemented in backend/apps/owasp/api/internal/queries/sponsor.py. Apply this behavior consistently to files in backend/apps/owasp (not just video.py), and ensure code paths that render sponsor lists follow this in-code sorting approach rather than pre-filtering NOT_SPONSOR entries before sorting.
Applied to files:
backend/apps/owasp/api/internal/nodes/committee.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). (6)
- GitHub Check: Run REST fuzz tests / Run Fuzz Tests
- GitHub Check: Run GraphQL fuzz tests / Run Fuzz Tests
- GitHub Check: Run frontend e2e tests
- GitHub Check: Run frontend unit tests
- GitHub Check: Run frontend accessibility tests
- GitHub Check: Run backend tests
🔇 Additional comments (2)
backend/apps/owasp/api/internal/nodes/committee.py (2)
1-10: Migration to strawberry_django.type looks correct.The class properly extends
GenericEntityNodeand exposes the appropriate model fields. The import structure is clean.
13-16: Null-safety checks properly implemented.The conditional access pattern (
root.owasp_repository.attr if root.owasp_repository else 0) correctly guards againstAttributeErrorwhen the nullable ForeignKey isNone. This addresses the previous review concern.Also applies to: 23-26, 28-31, 38-41
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
|
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
backend/apps/owasp/api/internal/queries/project.py (1)
37-64: Moveselect_related/prefetch_relatedfrom decorator to resolver body.Per the retrieved learnings and PR discussion, using
select_related/prefetch_relatedin@strawberry_django.fielddecorators for fields returning relationship lists can cause Strawberry to incorrectly expose those relations as queryable fields in the GraphQL schema. This is the root cause of the Schemathesis fuzz failures (e.g.,Snapshot has no field named 'repository').Either move the optimizations into the resolver body or rely on
DjangoOptimizerExtensionto auto-optimize based on the selection set.♻️ Proposed refactor
- `@strawberry_django.field`( - select_related=[ - "owasp_repository__organization", - "owasp_repository__owner__owasp_profile", - "owasp_repository__owner__user_badges__badge", - ], - prefetch_related=[ - "organizations", - "owners", - "repositories__organization", - "entity_leaders__member", - ], - ) + `@strawberry_django.field` def recent_projects(self, limit: int = 8) -> list[ProjectNode]: """Resolve recent projects. Args: limit (int): The maximum number of recent projects to return. Returns: list[ProjectNode]: A list of recent active projects. """ - return ( - Project.objects.filter(is_active=True).order_by("-created_at")[:limit] - if (limit := min(limit, MAX_RECENT_PROJECTS_LIMIT)) > 0 - else [] - ) + if (limit := min(limit, MAX_RECENT_PROJECTS_LIMIT)) <= 0: + return [] + + return ( + Project.objects.filter(is_active=True) + .select_related( + "owasp_repository__organization", + "owasp_repository__owner__owasp_profile", + "owasp_repository__owner__user_badges__badge", + ) + .prefetch_related( + "organizations", + "owners", + "repositories__organization", + "entity_leaders__member", + ) + .order_by("-created_at")[:limit] + )Based on learnings, decorator hints should only be used for custom querysets built from scratch in Query classes or for non-relationship fields, not for fields returning relationship lists.
🤖 Fix all issues with AI agents
In `@backend/apps/github/api/internal/queries/release.py`:
- Around line 18-24: The decorator on the relationship field uses
select_related/prefetch_related hints which traverse a reverse relation
(user_badges) and will raise a FieldError; remove the select_related and
prefetch_related arguments from the `@strawberry_django.field` decorator for this
relationship field so optimizer hints are not provided here, and if needed move
explicit queryset optimization into the resolver function (or rely on
DjangoOptimizerExtension to infer joins from the GraphQL selection).
In `@backend/apps/owasp/api/internal/nodes/board_of_directors.py`:
- Around line 21-34: The three resolver methods candidates, members, and
owasp_url on the BoardOfDirectors type are declared with a `root:
BoardOfDirectors` parameter which makes that parameter a GraphQL argument;
change each method signature to instance methods that use `self` (e.g., def
candidates(self) -> list[EntityMemberNode]) and call `self.get_candidates()`,
`self.get_members()`, and `self.owasp_url` respectively, keeping the
`@strawberry_django.field` decorators and return types intact so no extra GraphQL
arguments are exposed.
♻️ Duplicate comments (4)
backend/apps/owasp/api/internal/queries/project.py (1)
66-91: Same issue as flagged above forrecent_projects.The
select_related/prefetch_relatedin the decorator should be moved to the resolver body. This was already noted in a previous review comment.backend/apps/github/api/internal/nodes/issue.py (2)
53-61:.select_related().order_by()chain bypasses prefetch cache.Similar to the
is_mergedissue, calling.select_related("user").order_by("user__login")onroot.participant_interestscreates a new QuerySet that bypasses the prefetch cache, negating theprefetch_relatedhint.Additionally, based on learnings,
prefetch_relatedin the decorator for relationship-returning resolvers (returninglist[UserNode]) may cause schema exposure issues.♻️ Recommended fix: Remove decorator hint and sort in Python
- `@strawberry_django.field`(prefetch_related=["participant_interests__user"]) + `@strawberry_django.field` def interested_users(self, root: Issue) -> list[UserNode]: """Return all users who have expressed interest in this issue.""" - return [ - interest.user - for interest in root.participant_interests.select_related("user").order_by( - "user__login" - ) - ] + return sorted( + [interest.user for interest in root.participant_interests.all()], + key=lambda u: u.login or "", + )Note: If ordering is critical and the list is large, consider using
Prefetchwithto_attrand a pre-ordered queryset in the parent query instead.
48-51:.filter()bypasses prefetch cache, causing N+1 queries.Calling
.filter()on the prefetchedpull_requestsqueryset creates a new QuerySet that bypasses the prefetch cache, resulting in a database query per Issue. Filter in Python instead to utilize the cached objects.🐛 Proposed fix
`@strawberry_django.field`(prefetch_related=["pull_requests"]) def is_merged(self, root: Issue) -> bool: """Return True if this issue has at least one merged pull request.""" - return root.pull_requests.filter(state="closed", merged_at__isnull=False).exists() + return any( + pr.state == "closed" and pr.merged_at is not None + for pr in root.pull_requests.all() + )backend/apps/owasp/api/internal/queries/member_snapshot.py (1)
48-75: Removeselect_related/prefetch_relateddecorator hints on list resolver.This remains risky for list-returning relationship fields and can surface invalid fields in schema introspection. Prefer moving the optimizations into the queryset body or relying on
DjangoOptimizerExtension(). Based on learnings, avoid decorator hints on relationship list resolvers.
🧹 Nitpick comments (2)
backend/apps/owasp/api/internal/queries/snapshot.py (1)
36-46: Consider separating the limit clamping for readability.The walrus operator reassigning the parameter within the conditional works correctly, but is dense. A separate assignment would improve clarity.
♻️ Optional refactor for improved readability
def snapshots(self, limit: int = 12) -> list[SnapshotNode]: """Resolve snapshots.""" + limit = min(limit, MAX_LIMIT) + if limit <= 0: + return [] return ( Snapshot.objects.filter( status=Snapshot.Status.COMPLETED, ).order_by( "-created_at", - )[:limit] - if (limit := min(limit, MAX_LIMIT)) > 0 - else [] + )[:limit] )backend/apps/owasp/models/project.py (1)
222-224: Consider cachinglast_health_metricsif repeated access is common.
last_health_metricsnow performs a query each access; callers likehealth_scorecan trigger multiple hits. If it’s safe to cache per instance/request, a cached property can avoid duplicate queries.♻️ Possible change
-from functools import lru_cache +from functools import lru_cache, cached_property @@ - `@property` - def last_health_metrics(self) -> ProjectHealthMetrics | None: + `@cached_property` + def last_health_metrics(self) -> ProjectHealthMetrics | None: """Return last health metrics for the project.""" return self.health_metrics.order_by("-nest_created_at").first()
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (5)
frontend/src/types/__generated__/graphql.tsis excluded by!**/__generated__/**frontend/src/types/__generated__/issueQueries.generated.tsis excluded by!**/__generated__/**frontend/src/types/__generated__/menteeQueries.generated.tsis excluded by!**/__generated__/**frontend/src/types/__generated__/moduleQueries.generated.tsis excluded by!**/__generated__/**frontend/src/types/__generated__/programsQueries.generated.tsis excluded by!**/__generated__/**
📒 Files selected for processing (20)
.github/workflows/run-ci-cd.yaml.github/workflows/run-fuzz-tests.yamlbackend/apps/api/rest/v0/__init__.pybackend/apps/common/middlewares/block_null_characters.pybackend/apps/github/api/internal/nodes/issue.pybackend/apps/github/api/internal/nodes/milestone.pybackend/apps/github/api/internal/nodes/pull_request.pybackend/apps/github/api/internal/queries/issue.pybackend/apps/github/api/internal/queries/milestone.pybackend/apps/github/api/internal/queries/release.pybackend/apps/owasp/api/internal/nodes/board_of_directors.pybackend/apps/owasp/api/internal/queries/member_snapshot.pybackend/apps/owasp/api/internal/queries/project.pybackend/apps/owasp/api/internal/queries/project_health_metrics.pybackend/apps/owasp/api/internal/queries/snapshot.pybackend/apps/owasp/models/project.pybackend/apps/owasp/models/project_health_metrics.pybackend/tests/apps/owasp/api/internal/nodes/board_of_directors_test.pybackend/tests/fuzz/graphql_test.pybackend/tests/fuzz/rest_test.py
🚧 Files skipped from review as they are similar to previous changes (4)
- backend/tests/fuzz/rest_test.py
- backend/apps/common/middlewares/block_null_characters.py
- backend/tests/fuzz/graphql_test.py
- backend/tests/apps/owasp/api/internal/nodes/board_of_directors_test.py
🧰 Additional context used
🧠 Learnings (19)
📓 Common learnings
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
📚 Learning: 2026-01-08T15:10:51.510Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 0
File: :0-0
Timestamp: 2026-01-08T15:10:51.510Z
Learning: In Strawberry Django, select_related and prefetch_related parameters in the strawberry_django.field decorator are optimization hints for the Query Optimizer and should NOT expose those relations as queryable fields in the GraphQL schema. If fields are being incorrectly exposed, it may be a schema introspection tool bug (like Schemathesis) or a version-specific issue with strawberry-graphql-django.
Applied to files:
backend/apps/owasp/api/internal/queries/snapshot.pybackend/apps/owasp/api/internal/queries/project.pybackend/apps/github/api/internal/nodes/issue.pybackend/apps/owasp/api/internal/queries/member_snapshot.py
📚 Learning: 2026-01-09T08:40:58.858Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 0
File: :0-0
Timestamp: 2026-01-09T08:40:58.858Z
Learning: In Strawberry Django, select_related and prefetch_related parameters in strawberry_django.field decorators should NOT be used for fields that return objects through Django relationships (ManyToMany, ForeignKey reverse relations). These hints can be misinterpreted by Strawberry and expose unwanted fields in the schema. For relationship fields returning lists, either let DjangoOptimizerExtension optimize automatically, or apply select_related/prefetch_related inside the resolver method. Decorator hints are only appropriate for custom querysets built from scratch in Query classes or for non-relationship fields.
Applied to files:
backend/apps/owasp/api/internal/queries/snapshot.pybackend/apps/github/api/internal/queries/issue.pybackend/apps/owasp/models/project.pybackend/apps/owasp/api/internal/queries/project.pybackend/apps/github/api/internal/nodes/issue.pybackend/apps/owasp/api/internal/queries/member_snapshot.py
📚 Learning: 2025-11-23T11:37:26.253Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2606
File: backend/apps/api/rest/v0/project.py:43-48
Timestamp: 2025-11-23T11:37:26.253Z
Learning: In the OWASP Nest backend, `entity_leaders` is a `property` method defined in `RepositoryBasedEntityModel` (backend/apps/owasp/models/common.py) that returns a dynamically constructed QuerySet. It cannot be prefetched using standard `prefetch_related()` because Django's prefetch mechanism only works on model fields and relations, not property methods.
Applied to files:
backend/apps/owasp/api/internal/queries/snapshot.pybackend/apps/owasp/models/project.py
📚 Learning: 2025-07-31T07:05:25.056Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 0
File: :0-0
Timestamp: 2025-07-31T07:05:25.056Z
Learning: In the OWASP Nest project, Django views may not properly access authenticated users from sessions created by Strawberry GraphQL mutations. The issue occurs because Django's AuthenticationMiddleware doesn't always populate request.user from session data that GraphQL context successfully uses via info.context.request.user. The solution is to manually resolve users from session data using request.session.get('_auth_user_id') and User.objects.select_related('github_user').get(pk=user_id) to match the same authentication mechanism used by GraphQL context.
Applied to files:
backend/apps/owasp/api/internal/queries/snapshot.pybackend/apps/github/api/internal/nodes/issue.pybackend/apps/owasp/api/internal/queries/member_snapshot.py
📚 Learning: 2025-07-11T15:57:56.648Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: backend/apps/mentorship/graphql/queries/module.py:39-50
Timestamp: 2025-07-11T15:57:56.648Z
Learning: In the OWASP Nest mentorship GraphQL queries, Strawberry GraphQL automatically converts between Django Module instances and ModuleNode types, so methods can return Module instances directly without manual conversion even when typed as ModuleNode.
Applied to files:
backend/apps/owasp/api/internal/queries/snapshot.pybackend/apps/owasp/api/internal/queries/project.pybackend/apps/owasp/api/internal/queries/member_snapshot.pybackend/apps/owasp/api/internal/nodes/board_of_directors.py
📚 Learning: 2025-12-31T05:17:39.659Z
Learnt from: kart-u
Repo: OWASP/Nest PR: 3101
File: backend/apps/common/extensions.py:92-98
Timestamp: 2025-12-31T05:17:39.659Z
Learning: In this codebase, import OperationType for GraphQL operations from the graphql-core package rather than from strawberry. Use 'from graphql import OperationType'. Strawberry re-exports via graphql-core internally, so relying on strawberry's API may be brittle. Apply this rule to all Python files that deal with GraphQL operation types; ensure imports come from graphql (graphql-core) and not from strawberry packages. This improves compatibility and avoids coupling to strawberry's internals.
Applied to files:
backend/apps/owasp/api/internal/queries/snapshot.pybackend/apps/github/api/internal/queries/release.pybackend/apps/github/api/internal/queries/issue.pybackend/apps/owasp/api/internal/queries/project_health_metrics.pybackend/apps/github/api/internal/nodes/pull_request.pybackend/apps/owasp/models/project_health_metrics.pybackend/apps/github/api/internal/queries/milestone.pybackend/apps/api/rest/v0/__init__.pybackend/apps/owasp/models/project.pybackend/apps/github/api/internal/nodes/milestone.pybackend/apps/owasp/api/internal/queries/project.pybackend/apps/github/api/internal/nodes/issue.pybackend/apps/owasp/api/internal/queries/member_snapshot.pybackend/apps/owasp/api/internal/nodes/board_of_directors.py
📚 Learning: 2026-01-01T17:48:23.963Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2948
File: backend/apps/owasp/management/commands/owasp_generate_community_snapshot_video.py:41-47
Timestamp: 2026-01-01T17:48:23.963Z
Learning: In Django code, be aware that a QuerySet's boolean evaluation (e.g., if not queryset) runs a database query to determine emptiness. While it is technically valid to use the queryset in a boolean context, use queryset.exists() for existence checks to avoid unnecessary queries and improve performance. Applicable broadly to Python/Django files rather than just this specific path.
Applied to files:
backend/apps/owasp/api/internal/queries/snapshot.pybackend/apps/github/api/internal/queries/release.pybackend/apps/github/api/internal/queries/issue.pybackend/apps/owasp/api/internal/queries/project_health_metrics.pybackend/apps/github/api/internal/nodes/pull_request.pybackend/apps/owasp/models/project_health_metrics.pybackend/apps/github/api/internal/queries/milestone.pybackend/apps/api/rest/v0/__init__.pybackend/apps/owasp/models/project.pybackend/apps/github/api/internal/nodes/milestone.pybackend/apps/owasp/api/internal/queries/project.pybackend/apps/github/api/internal/nodes/issue.pybackend/apps/owasp/api/internal/queries/member_snapshot.pybackend/apps/owasp/api/internal/nodes/board_of_directors.py
📚 Learning: 2026-01-01T18:57:05.007Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2948
File: backend/apps/owasp/video.py:189-215
Timestamp: 2026-01-01T18:57:05.007Z
Learning: In the OWASP backend area, maintain the established pattern: when dealing with sponsors, include all entries from Sponsor.objects.all() (including NOT_SPONSOR) and perform in-memory sorting using the same criteria/pattern used by the GraphQL sponsor query implemented in backend/apps/owasp/api/internal/queries/sponsor.py. Apply this behavior consistently to files in backend/apps/owasp (not just video.py), and ensure code paths that render sponsor lists follow this in-code sorting approach rather than pre-filtering NOT_SPONSOR entries before sorting.
Applied to files:
backend/apps/owasp/api/internal/queries/snapshot.pybackend/apps/owasp/api/internal/queries/project_health_metrics.pybackend/apps/owasp/models/project_health_metrics.pybackend/apps/owasp/models/project.pybackend/apps/owasp/api/internal/queries/project.pybackend/apps/owasp/api/internal/queries/member_snapshot.pybackend/apps/owasp/api/internal/nodes/board_of_directors.py
📚 Learning: 2025-12-26T06:57:30.908Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: docker-compose/fuzz.yaml:70-83
Timestamp: 2025-12-26T06:57:30.908Z
Learning: In the fuzz testing environment (docker-compose/fuzz.yaml), the data-loader and graphql services are orchestrated in separate phases via the Makefile's test-fuzz target, not run simultaneously. The data is loaded to completion first, then the graphql fuzzer is started separately against the populated database. The docker-compose dependencies reflect runtime health checks rather than orchestration order.
Applied to files:
.github/workflows/run-fuzz-tests.yaml.github/workflows/run-ci-cd.yaml
📚 Learning: 2025-12-26T06:09:08.868Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 3041
File: .github/workflows/run-ci-cd.yaml:233-243
Timestamp: 2025-12-26T06:09:08.868Z
Learning: For the OWASP/Nest repository, Redis image versions should remain consistent across all environments (production, staging, local, E2E, and CI/CD E2E tests). When upgrading Redis, update all docker-compose files and CI/CD workflow configurations together to maintain environment parity.
Applied to files:
.github/workflows/run-fuzz-tests.yaml.github/workflows/run-ci-cd.yaml
📚 Learning: 2025-12-21T19:03:59.068Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1139
File: .github/workflows/setup-backend-environment/action.yaml:16-27
Timestamp: 2025-12-21T19:03:59.068Z
Learning: Composite actions (runs: using: composite) execute as steps within the calling job's context and can access the job context, including job.services.* properties (e.g., job.services.<service_id>.id, job.services.<service_id>.ports). Service containers must be defined at the job level, but a composite action's steps can reference them via the job context.
Applied to files:
.github/workflows/run-fuzz-tests.yaml.github/workflows/run-ci-cd.yaml
📚 Learning: 2026-01-06T12:38:23.460Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 3122
File: backend/apps/owasp/api/internal/nodes/project.py:52-61
Timestamp: 2026-01-06T12:38:23.460Z
Learning: In backend/apps/owasp/api/internal/nodes/project.py, the health_metrics_list method intentionally orders by nest_created_at ascending (oldest first) to return metrics in chronological order for trend analysis, which differs from health_metrics_latest that orders descending to get the most recent metric.
Applied to files:
backend/apps/owasp/api/internal/queries/project_health_metrics.pybackend/apps/owasp/models/project_health_metrics.pybackend/apps/owasp/models/project.py
📚 Learning: 2025-12-30T15:05:23.157Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 0
File: :0-0
Timestamp: 2025-12-30T15:05:23.157Z
Learning: In the OWASP/Nest repository, four functions in backend/apps/slack/utils.py (get_gsoc_projects, get_news_data, get_staff_data, get_posts_data) have unbounded lru_cache decorators that can cause memory accumulation during fuzz testing. These should have explicit maxsize limits (e.g., maxsize=16) to prevent OOM issues.
Applied to files:
backend/apps/owasp/api/internal/queries/project_health_metrics.py
📚 Learning: 2025-08-04T15:55:08.017Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1967
File: backend/apps/owasp/api/internal/filters/project_health_metrics.py:24-27
Timestamp: 2025-08-04T15:55:08.017Z
Learning: In the OWASP Nest project, the `is_active` filter in `ProjectHealthMetricsFilter` is intentionally designed as a workaround to eliminate inactive projects from the dashboard. It only filters FOR active projects when `value=True`, and returns an empty Q() when `value=False` to avoid showing inactive projects. This is not meant to be a general boolean filter but a specific solution to exclude inactive projects from the project health metrics dashboard.
Applied to files:
backend/apps/owasp/api/internal/queries/project_health_metrics.pybackend/apps/owasp/models/project_health_metrics.pybackend/apps/owasp/models/project.py
📚 Learning: 2025-06-21T12:22:01.889Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/GradientRadialChart.tsx:113-113
Timestamp: 2025-06-21T12:22:01.889Z
Learning: In the OWASP Nest project, health metrics requirements (like lastCommitDaysRequirement, lastReleaseDaysRequirement) should never be 0. A requirement value of 0 is considered invalid and should result in displaying 0 on the radial chart.
Applied to files:
backend/apps/owasp/models/project_health_metrics.py
📚 Learning: 2025-09-08T07:14:17.047Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 2211
File: backend/apps/slack/common/handlers/calendar_events.py:75-75
Timestamp: 2025-09-08T07:14:17.047Z
Learning: In this Django codebase, ValidationError objects have a .message attribute that can be accessed directly (e.g., e.message) for error handling, as evidenced by consistent usage in backend/apps/core/api/internal/algolia.py and backend/apps/slack/common/handlers/calendar_events.py.
Applied to files:
backend/apps/api/rest/v0/__init__.py
📚 Learning: 2025-09-21T17:04:48.154Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/snapshots/[id]/page.tsx:0-0
Timestamp: 2025-09-21T17:04:48.154Z
Learning: User rudransh-shrivastava confirmed that suggested type safety improvements during Apollo Client migration were no longer relevant, reinforcing their preference to keep migration PRs focused on core migration changes rather than additional improvements.
Applied to files:
backend/apps/owasp/api/internal/queries/member_snapshot.py
📚 Learning: 2025-07-13T05:55:46.436Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: backend/apps/mentorship/graphql/mutations/program.py:166-166
Timestamp: 2025-07-13T05:55:46.436Z
Learning: In the OWASP Nest mentorship GraphQL mutations, Strawberry GraphQL automatically converts between Django Program instances and ProgramNode types, so mutations can return Program instances directly without manual conversion even when typed as ProgramNode, similar to the Module/ModuleNode pattern.
Applied to files:
backend/apps/owasp/api/internal/nodes/board_of_directors.py
🧬 Code graph analysis (9)
backend/apps/owasp/api/internal/queries/snapshot.py (2)
backend/apps/owasp/api/internal/nodes/snapshot.py (1)
SnapshotNode(25-53)backend/apps/owasp/models/snapshot.py (2)
Snapshot(7-77)Status(19-23)
backend/apps/github/api/internal/queries/issue.py (1)
backend/apps/github/api/internal/nodes/issue.py (1)
IssueNode(22-61)
backend/apps/owasp/api/internal/queries/project_health_metrics.py (1)
backend/apps/owasp/models/project_health_metrics.py (2)
ProjectHealthMetrics(18-246)get_latest_health_metrics(166-181)
backend/apps/owasp/models/project_health_metrics.py (3)
backend/apps/github/api/internal/nodes/organization.py (1)
stats(43-71)frontend/src/types/__generated__/graphql.ts (1)
ProjectHealthStatsNode(595-609)backend/apps/owasp/api/internal/nodes/project_health_stats.py (1)
ProjectHealthStatsNode(7-21)
backend/apps/github/api/internal/queries/milestone.py (3)
backend/apps/github/api/internal/nodes/milestone.py (1)
MilestoneNode(22-48)backend/apps/github/models/generic_issue_model.py (2)
GenericIssueModel(10-77)State(18-20)backend/apps/github/models/milestone.py (1)
Milestone(10-112)
backend/apps/owasp/models/project.py (1)
backend/apps/owasp/models/project_health_metrics.py (1)
ProjectHealthMetrics(18-246)
backend/apps/github/api/internal/nodes/milestone.py (5)
backend/apps/github/api/internal/nodes/user.py (1)
UserNode(27-108)backend/apps/github/api/internal/nodes/issue.py (2)
organization_name(30-36)repository_name(39-41)backend/apps/github/api/internal/nodes/pull_request.py (2)
organization_name(25-31)repository_name(34-36)backend/apps/github/api/internal/nodes/release.py (2)
organization_name(26-32)repository_name(46-48)backend/apps/github/api/internal/queries/repository.py (1)
repository(17-38)
backend/apps/github/api/internal/nodes/issue.py (3)
backend/apps/github/api/internal/nodes/pull_request.py (3)
PullRequestNode(19-41)organization_name(25-31)repository_name(34-36)backend/apps/github/api/internal/nodes/release.py (2)
organization_name(26-32)repository_name(46-48)backend/apps/github/models/issue.py (1)
Issue(19-235)
backend/apps/owasp/api/internal/nodes/board_of_directors.py (2)
frontend/src/types/__generated__/graphql.ts (3)
BoardOfDirectorsNode(49-59)Node(457-460)EntityMemberNode(141-153)backend/apps/owasp/models/board_of_directors.py (4)
BoardOfDirectors(16-59)get_candidates(41-49)get_members(51-59)owasp_url(32-39)
⏰ 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). (7)
- GitHub Check: Run GraphQL fuzz tests / Run Fuzz Tests
- GitHub Check: Run REST fuzz tests / Run Fuzz Tests
- GitHub Check: Run backend tests
- GitHub Check: Run frontend e2e tests
- GitHub Check: Run frontend unit tests
- GitHub Check: Run frontend accessibility tests
- GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (50)
backend/apps/api/rest/v0/__init__.py (2)
6-8: Import is appropriate for the new handler.Nice, this keeps the handler registration explicit and clear.
107-114: ValidationError handler looks good.Centralized 400 response with a stable payload is a solid addition.
backend/apps/owasp/api/internal/queries/project.py (3)
11-14: LGTM!The constants for query limits and validation provide clear, reasonable boundaries for input sanitization.
21-35: LGTM!Single-object lookup with proper exception handling. Using
@strawberry_django.fieldwithout optimization hints is appropriate here sinceDjangoOptimizerExtensioncan optimize based on the actual selection set.
93-104: LGTM!The resolver correctly uses
@strawberry_django.fieldwithout optimization hints, performs efficient existence checks with.exists(), and properly handles the case wheregithub_user.nameisNone.backend/apps/owasp/api/internal/queries/snapshot.py (3)
1-10: LGTM!Good addition of the
MAX_LIMITconstant to bound query results and prevent unbounded data retrieval.
16-25: LGTM!Appropriate use of
@strawberry_django.fieldwithout prefetch hints for single-object retrieval. The optimizer will handle nested field prefetching based on the GraphQL selection set.
27-35: LGTM!Query-level
prefetch_relatedis appropriate here. The prefetch paths correctly match the M2M relations on the Snapshot model, and the DjangoOptimizerExtension will use these hints when nested fields are selected in the GraphQL query.backend/apps/github/api/internal/nodes/pull_request.py (3)
22-22: LGTM!Clean field declaration for the
authorrelationship. LettingDjangoOptimizerExtensionhandle the optimization automatically is the correct approach for relationship fields.
24-31: LGTM!The
select_relatedhint is appropriate here since this resolver returns a scalar value (str | None), not a relationship object. The null-safety checks are correct.
33-41: LGTM!Both
repository_nameandurlresolvers follow the correct pattern with appropriateselect_relatedhints for scalar-returning resolvers.backend/apps/github/api/internal/nodes/issue.py (3)
25-27: LGTM!Field declarations for relationship types without explicit decorator hints allow
DjangoOptimizerExtensionto handle optimization based on the actual GraphQL selection set. This aligns with the recommended approach per learnings.
29-41: LGTM!Both
organization_nameandrepository_nameresolvers correctly useselect_relatedhints for scalar-returning resolvers with proper null-safety checks. Consistent with the pattern inPullRequestNode.
43-46: LGTM!The
labelsresolver correctly iterates over prefetched objects using list comprehension, which properly utilizes the prefetch cache.backend/apps/owasp/models/project.py (7)
10-10: LGTM for the new PostgreSQL index imports.
32-32: TYPE_CHECKING import adjustment looks fine.
200-213: Queryset optimization for issues is solid.
263-276: Pull request queryset enrichment looks good.
299-301: Releaseselect_relatedadditions look good.
307-317: Recent milestones queryset updates look good.
53-64: [Your rewritten review comment text here]
[Exactly ONE classification tag]backend/apps/owasp/api/internal/nodes/board_of_directors.py (1)
10-16: No issues to highlight here.backend/apps/owasp/api/internal/queries/project_health_metrics.py (2)
5-5: LGTM for the new pagination constants/import.No concerns here.
Also applies to: 14-15
58-60: Decorator change looks good.backend/apps/owasp/api/internal/queries/member_snapshot.py (2)
4-10: Imports and MAX_LIMIT look fine.
17-43: member_snapshot query updates look good.backend/apps/owasp/models/project_health_metrics.py (3)
7-7: No issues here.
173-181: Subquery-based latest metrics lookup looks good.
191-245: Stats aggregation changes look good.backend/apps/github/api/internal/queries/release.py (3)
4-11: LGTM: imports and MAX_LIMIT addition.
74-74: Limit clamping looks good.
61-70: Distinct logic drops repository dimension.The docstring promises uniqueness per author and repository, but the window partitions only by
author_id, which collapses releases across different repositories for the same author. Either includerepository_idin the partition or update the docstring to match the intended semantics.🔧 Proposed fix (if distinct should be per author + repository)
- partition_by=[F("author_id")], + partition_by=[F("author_id"), F("repository_id")],backend/apps/github/api/internal/queries/milestone.py (4)
6-14: LGTM: strawberry_django import + MAX_LIMIT.
16-22: Enum now string-backed with.value— good.
28-45: LGTM: field decorator + expanded filtering params.
77-91: LGTM: distinct subquery + limit clamping.backend/apps/github/api/internal/queries/issue.py (2)
4-11: LGTM: imports and MAX_LIMIT.
60-70: LGTM: centralized filters + clamped limit.Also applies to: 85-85
backend/apps/github/api/internal/nodes/milestone.py (4)
25-25: LGTM: author field definition.
27-34: LGTM: organization_name resolver conversion.
36-43: LGTM: progress resolver conversion.
45-48: LGTM: repository_name resolver conversion..github/workflows/run-fuzz-tests.yaml (5)
3-15: Inputs are well scoped.Defaulting
rest-urlkeeps REST fuzz runs plug‑and‑play while still allowing overrides.
57-91: Backend bring‑up and data load flow looks solid.Starting the app, waiting for readiness, and using
set -euo pipefailaroundpg_restoreis a reliable sequence.
93-105: Fuzz image build step looks good.Caching and tagging are set up cleanly for CI reuse.
107-118: Env propagation into the fuzz container is correct.
TEST_FILEandREST_URLare forwarded as expected.
16-20: [UNABLE TO VERIFY] Unable to access the repository to confirm the specific claims about this workflow file.I verified that the general principles in the review comment are correct:
actions/checkoutdoes requirecontents: readpermission, and reusable workflows inherit permissions from their callers. However, I cannot confirm:
- Whether this file is actually a reusable workflow (
on: workflow_call)- Whether a caller workflow exists that sets
permissions: {}- The current state of the file in the repository
The repository could not be cloned in the sandbox environment, and the file could not be located via public web search. To complete this verification, manual inspection of the workflow file and its callers is necessary.
If this is indeed a reusable workflow with a caller that sets
permissions: {}, the fix is appropriate and critical..github/workflows/run-ci-cd.yaml (3)
264-270: Redis health check update looks fine.The simplified
redis-cli pingaligns with no‑auth cache usage in CI.
292-293: Redis auth disablement for e2e backend is consistent.Good to make CI backend explicitly align with the cache service.
384-401: Delegation to the shared fuzz workflow is clean.Nice reuse with dedicated GraphQL and REST fuzz jobs.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
* Migrate to schemathesis and add rest fuzz tests * Apply cspell * Update Fuzz Dockerfile context * Update rest auth for fuzz * Optimize Project Health Stats query and split rest and graphql tests * Split rest and graphql tests workflows * Update ci/cd * Apply rabbit suggestions * Update ci/cd * Apply rabbit's suggestions * Increase number of examples * Apply rabbit's suggestions * Apply pre-commit checks * Update CI/CD * Update makefile * Update CI/CD * Update CI/CD * Update ci/cd * Update ci/cd * Update CI/CD * Update settings.base.py and ci/cd * Update configuration and ci/cd * Update alphabitical order in env files * Fix negative indexing * Add EscapeNullCharactersMiddleware * Update middleware, schemathesis config and add HTTP BadRequest status code to the rest api docs * Update rest api schema * Update tests * Optimize recentIssues * Add optimiazations and fixes * Update tests, ci/cd and apply rabbit suggestions * Optimize N+1 queries * Update tests * Update rest schema and add a name for Fuzz Tests job in CI/CD * Fix negative indexing * Update project health metrics filters and pagination * Update mentorship app, ci/cd, and entrypoint * Add trigram index to project * Update nest.dump * Update entrypoint * Apply checks * Add QueryDepthLimiter * Add optimizations * Update tests * Update CI/CD * Add fixes * Apply rabbit's suggestion * Refactor docker files * Apply cspell * Refactor limits * Update milestone enum and rest api endpoints * Apply middleware suggestions * Migrate to strawberry_django.field * Update REDIS_AUTH_ENABLED default value * Update queries to use strawberry_django.field * Apply rabbit suggestions * Update tests and appply rabbit suggestion * Fix pagination.limit * Add optimizations and fixes * Update code * Add optimizations * Add optimizations * Add optimizations * Add fixes * Add milestone index migration * Update nest.dump * Add optimizations and fixes * Update snapshot query * Update backend tests * Update project model * Apply rabbit suggestion * Apply rabbit suggestions * Apply rabbit suggestion and update tests * Update code --------- Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
* Migrate to schemathesis and add rest fuzz tests * Apply cspell * Update Fuzz Dockerfile context * Update rest auth for fuzz * Optimize Project Health Stats query and split rest and graphql tests * Split rest and graphql tests workflows * Update ci/cd * Apply rabbit suggestions * Update ci/cd * Apply rabbit's suggestions * Increase number of examples * Apply rabbit's suggestions * Apply pre-commit checks * Update CI/CD * Update makefile * Update CI/CD * Update CI/CD * Update ci/cd * Update ci/cd * Update CI/CD * Update settings.base.py and ci/cd * Update configuration and ci/cd * Update alphabitical order in env files * Fix negative indexing * Add EscapeNullCharactersMiddleware * Update middleware, schemathesis config and add HTTP BadRequest status code to the rest api docs * Update rest api schema * Update tests * Optimize recentIssues * Add optimiazations and fixes * Update tests, ci/cd and apply rabbit suggestions * Optimize N+1 queries * Update tests * Update rest schema and add a name for Fuzz Tests job in CI/CD * Fix negative indexing * Update project health metrics filters and pagination * Update mentorship app, ci/cd, and entrypoint * Add trigram index to project * Update nest.dump * Update entrypoint * Apply checks * Add QueryDepthLimiter * Add optimizations * Update tests * Update CI/CD * Add fixes * Apply rabbit's suggestion * Refactor docker files * Apply cspell * Refactor limits * Update milestone enum and rest api endpoints * Apply middleware suggestions * Migrate to strawberry_django.field * Update REDIS_AUTH_ENABLED default value * Update queries to use strawberry_django.field * Apply rabbit suggestions * Update tests and appply rabbit suggestion * Fix pagination.limit * Add optimizations and fixes * Update code * Add optimizations * Add optimizations * Add optimizations * Add fixes * Add milestone index migration * Update nest.dump * Add optimizations and fixes * Update snapshot query * Update backend tests * Update project model * Apply rabbit suggestion * Apply rabbit suggestions * Apply rabbit suggestion and update tests * Update code --------- Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
* Migrate to schemathesis and add rest fuzz tests * Apply cspell * Update Fuzz Dockerfile context * Update rest auth for fuzz * Optimize Project Health Stats query and split rest and graphql tests * Split rest and graphql tests workflows * Update ci/cd * Apply rabbit suggestions * Update ci/cd * Apply rabbit's suggestions * Increase number of examples * Apply rabbit's suggestions * Apply pre-commit checks * Update CI/CD * Update makefile * Update CI/CD * Update CI/CD * Update ci/cd * Update ci/cd * Update CI/CD * Update settings.base.py and ci/cd * Update configuration and ci/cd * Update alphabitical order in env files * Fix negative indexing * Add EscapeNullCharactersMiddleware * Update middleware, schemathesis config and add HTTP BadRequest status code to the rest api docs * Update rest api schema * Update tests * Optimize recentIssues * Add optimiazations and fixes * Update tests, ci/cd and apply rabbit suggestions * Optimize N+1 queries * Update tests * Update rest schema and add a name for Fuzz Tests job in CI/CD * Fix negative indexing * Update project health metrics filters and pagination * Update mentorship app, ci/cd, and entrypoint * Add trigram index to project * Update nest.dump * Update entrypoint * Apply checks * Add QueryDepthLimiter * Add optimizations * Update tests * Update CI/CD * Add fixes * Apply rabbit's suggestion * Refactor docker files * Apply cspell * Refactor limits * Update milestone enum and rest api endpoints * Apply middleware suggestions * Migrate to strawberry_django.field * Update REDIS_AUTH_ENABLED default value * Update queries to use strawberry_django.field * Apply rabbit suggestions * Update tests and appply rabbit suggestion * Fix pagination.limit * Add optimizations and fixes * Update code * Add optimizations * Add optimizations * Add optimizations * Add fixes * Add milestone index migration * Update nest.dump * Add optimizations and fixes * Update snapshot query * Update backend tests * Update project model * Apply rabbit suggestion * Apply rabbit suggestions * Apply rabbit suggestion and update tests * Update code --------- Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
* Migrate to schemathesis and add rest fuzz tests * Apply cspell * Update Fuzz Dockerfile context * Update rest auth for fuzz * Optimize Project Health Stats query and split rest and graphql tests * Split rest and graphql tests workflows * Update ci/cd * Apply rabbit suggestions * Update ci/cd * Apply rabbit's suggestions * Increase number of examples * Apply rabbit's suggestions * Apply pre-commit checks * Update CI/CD * Update makefile * Update CI/CD * Update CI/CD * Update ci/cd * Update ci/cd * Update CI/CD * Update settings.base.py and ci/cd * Update configuration and ci/cd * Update alphabitical order in env files * Fix negative indexing * Add EscapeNullCharactersMiddleware * Update middleware, schemathesis config and add HTTP BadRequest status code to the rest api docs * Update rest api schema * Update tests * Optimize recentIssues * Add optimiazations and fixes * Update tests, ci/cd and apply rabbit suggestions * Optimize N+1 queries * Update tests * Update rest schema and add a name for Fuzz Tests job in CI/CD * Fix negative indexing * Update project health metrics filters and pagination * Update mentorship app, ci/cd, and entrypoint * Add trigram index to project * Update nest.dump * Update entrypoint * Apply checks * Add QueryDepthLimiter * Add optimizations * Update tests * Update CI/CD * Add fixes * Apply rabbit's suggestion * Refactor docker files * Apply cspell * Refactor limits * Update milestone enum and rest api endpoints * Apply middleware suggestions * Migrate to strawberry_django.field * Update REDIS_AUTH_ENABLED default value * Update queries to use strawberry_django.field * Apply rabbit suggestions * Update tests and appply rabbit suggestion * Fix pagination.limit * Add optimizations and fixes * Update code * Add optimizations * Add optimizations * Add optimizations * Add fixes * Add milestone index migration * Update nest.dump * Add optimizations and fixes * Update snapshot query * Update backend tests * Update project model * Apply rabbit suggestion * Apply rabbit suggestions * Apply rabbit suggestion and update tests * Update code --------- Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>



Proposed change
Resolves #3100
Add the PR description here.
Checklist
make check-testlocally and all tests passed