Skip to content

Conversation

@sonu1680
Copy link

Proposed change

Resolves #2649

This pull request extracts hardcoded numeric values (magic numbers) from the
project.py mixin into descriptive module-level constants.

The goal is to improve readability, maintainability, and consistency within the
codebase by avoiding unnamed literal values inside methods.

What was changed

  • Added named constants at the top of backend/apps/owasp/models/mixins/project.py
  • Replaced all occurrences of related magic numbers with the new constants
  • Ensured the refactor does not change behavior or logic
  • Code quality checks and tests were run locally using make check-test

Checklist

  • I've read and followed the contributing guidelines.
  • I've run make check-test locally; all checks and tests passed.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 15, 2025

Summary by CodeRabbit

  • Refactor
    • Extracted configuration constants for improved code maintainability and consistency
    • Enhanced type annotations across utility functions for better code safety and reliability

Walkthrough

Extracts hard-coded numeric literals into module-level constants and strengthens type annotations: adds MAX_HEALTH_SCORE, SOURCE_MAX_LENGTH, commit-related length constants; updates model field lengths and idx_health_score behavior; and adds/adjusts type hints in common utilities.

Changes

Cohort / File(s) Summary
OWASP project mixin
backend/apps/owasp/models/mixins/project.py
Added MAX_HEALTH_SCORE = 100; idx_health_score returns MAX_HEALTH_SCORE when settings.IS_PRODUCTION_ENVIRONMENT is true instead of a hard-coded 100.
AI context model
backend/apps/ai/models/context.py
Added SOURCE_MAX_LENGTH = 100; updated Context.source from max_length=100 to max_length=SOURCE_MAX_LENGTH.
Common utilities (type hints)
backend/apps/common/utils.py
Added typing imports and explicit type hints; updated signatures: clean_url(url: Optional[str]) -> Optional[str], get_user_ip_address(request: HttpRequest) -> str, join_values(fields: Iterable[Any], ...) -> str, `natural_date(value: int
GitHub commit model
backend/apps/github/models/commit.py
Added MAX_SHA_LENGTH = 64, MESSAGE_PREVIEW_LENGTH = 100, SHORT_SHA_LENGTH = 7; sha field now max_length=MAX_SHA_LENGTH; __str__ uses SHORT_SHA_LENGTH and MESSAGE_PREVIEW_LENGTH instead of hard-coded values.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Areas needing extra attention:
    • Model field length changes and any migrations/serializers referencing those fields (ai.models.context, github.models.commit).
    • Behavior change in idx_health_score for production flag (owasp.models.mixins.project.py).
    • Call sites and type-checking impacts from updated signatures in common/utils.py.

Possibly related PRs

Suggested reviewers

  • arkid15r

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR partially addresses the linked issue #2649. While it extracts constants in project.py, the scope requires extracting magic numbers from both backend/apps/github/models/mixins/.py and backend/apps/owasp/models/mixins/.py files. Complete the refactoring by extracting magic numbers in other mixin files (e.g., backend/apps/github/models/mixins/*.py) as specified in issue #2649 scope, or scope this PR to project.py only and create follow-up PRs for remaining files.
Out of Scope Changes check ⚠️ Warning The PR contains out-of-scope changes beyond the stated objective. Changes to context.py, common/utils.py, and commit.py address unrelated refactoring goals outside the linked issue #2649. Remove changes to backend/apps/ai/models/context.py, backend/apps/common/utils.py, and backend/apps/github/models/commit.py. Create separate PRs for these unrelated refactoring tasks if they are needed.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title correctly identifies the main change: extracting magic numbers to constants in project.py, matching the primary file modified.
Description check ✅ Passed The description is directly related to the changeset, explaining the extraction of magic numbers to constants and referencing issue #2649.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a21c1e and 2549bed.

📒 Files selected for processing (2)
  • backend/apps/ai/models/context.py (2 hunks)
  • backend/apps/common/utils.py (7 hunks)
🧰 Additional context used
🪛 Ruff (0.14.4)
backend/apps/common/utils.py

15-15: Import from collections.abc instead: Iterable

Import from collections.abc

(UP035)


16-16: Move third-party import django.http.HttpRequest into a type-checking block

Move into type-checking block

(TC002)

🔇 Additional comments (9)
backend/apps/ai/models/context.py (2)

23-24: Consistent application of the constant.

The CharField correctly uses the new SOURCE_MAX_LENGTH constant, ensuring consistency with the defined constraint.


13-13: Constant extraction verified—no production code relies on hardcoded value.

The search confirms no production code in the codebase depends on a hardcoded 100 for the source field constraint. Test files properly validate the max_length boundary (accepting 100 chars, rejecting 101), confirming the SOURCE_MAX_LENGTH constant is correctly integrated into the model definition.

backend/apps/common/utils.py (7)

53-53: Good addition of Optional type annotation.

The type signature correctly reflects that clean_url can accept and return None, improving type safety and documentation.


92-92: Good addition of HttpRequest type annotation.

The explicit HttpRequest type annotation improves IDE support and type checking for this function.


109-109: Good use of Iterable for broader type acceptance.

Using Iterable[Any] instead of list allows the function to accept any iterable type (tuples, sets, generators), making it more flexible.


123-123: Good addition of datetime to union type.

The type signature now correctly documents all accepted input types including datetime objects, improving type safety.


143-143: Good addition of Optional type annotation for unit parameter.

The type signature correctly reflects that the unit parameter is optional and can be None, improving type clarity.


200-200: Good addition of Optional type annotation.

The type signature correctly reflects that validate_url can accept None values, improving type safety and null handling documentation.


15-16: Type annotations are beneficial but appear outside PR scope.

While the type annotation improvements in this file enhance code quality and maintainability, they appear unrelated to the stated PR objective of extracting magic numbers from backend/apps/owasp/models/mixins/project.py. Consider whether these changes should be in a separate PR focused on type safety improvements, or ensure the PR description accurately reflects all changes being made.

Also applies to: 53-53, 92-92, 109-109, 123-123, 143-143, 200-200


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

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
backend/apps/owasp/models/mixins/project.py (1)

14-14: Well done extracting the magic number!

The constant name is descriptive and follows the established naming convention. One minor consideration: since idx_health_score returns float | None, you might consider defining this as HEALTH_SCORE_MAX = 100.0 for strict type consistency, though Python's numeric type coercion makes this a low-priority refinement.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a2a8c86 and 1d255de.

📒 Files selected for processing (1)
  • backend/apps/owasp/models/mixins/project.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/apps/owasp/models/mixins/project.py (1)
backend/apps/owasp/models/project.py (1)
  • health_score (139-141)
🔇 Additional comments (1)
backend/apps/owasp/models/mixins/project.py (1)

41-44: LGTM! Magic number successfully replaced.

The refactor correctly uses the named constant while preserving the existing logic. The TODO comment appropriately documents that returning the maximum score in production is temporary behavior.

Copy link
Collaborator

@rudransh-shrivastava rudransh-shrivastava left a comment

Choose a reason for hiding this comment

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

Hi, I found some more magic numbers

  • at backend/apps/github/models/mixins/release.py line 40
  • not mixins, but you might check them as well: backend/apps/github/models/commit.py lines 62 and 63

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d255de and 9a21c1e.

📒 Files selected for processing (4)
  • backend/apps/ai/models/context.py (2 hunks)
  • backend/apps/common/utils.py (7 hunks)
  • backend/apps/github/models/commit.py (3 hunks)
  • backend/apps/owasp/models/mixins/project.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/apps/owasp/models/mixins/project.py
🧰 Additional context used
🪛 Ruff (0.14.4)
backend/apps/common/utils.py

14-14: Import from collections.abc instead: Iterable

Import from collections.abc

(UP035)


15-15: Move third-party import django.http.HttpRequest into a type-checking block

Move into type-checking block

(TC002)

🔇 Additional comments (6)
backend/apps/ai/models/context.py (2)

13-13: LGTM! Well-named constant.

The constant name is descriptive and follows Python naming conventions for module-level constants.


23-24: LGTM! Magic number successfully extracted.

The hardcoded 100 has been correctly replaced with the SOURCE_MAX_LENGTH constant, improving code maintainability while preserving the original behavior.

backend/apps/github/models/commit.py (3)

34-38: LGTM! Field definition updated correctly.

The max_length parameter now uses the MAX_SHA_LENGTH constant, successfully extracting the magic number while preserving the field's behavior.


64-68: LGTM! Magic numbers successfully extracted from str method.

The hardcoded slice indices have been correctly replaced with named constants (SHORT_SHA_LENGTH and MESSAGE_PREVIEW_LENGTH), making the code more maintainable and self-documenting.


10-12: <!-- [scratchpad_start]
[task review_file_2/3 review_segment_1/3 verification_sha_length - COMPLETED]
Final verification of MAX_SHA_LENGTH = 64
[observations]

  • Git commit SHA: SHA-1 = 160-bit (20-byte) hash = 40-character hexadecimal string
  • All sources confirm: full Git SHA-1 is 40 characters
  • GitHub API returns 40-character SHA-1 hashes for commits (confirmed in search result 15-12, 18-35)
  • Short SHA (displayed by Git and GitHub): 7 characters (confirmed by multiple sources)
  • SHORT_SHA_LENGTH = 7 in the code is correct
  • MAX_SHA_LENGTH = 64 in the code exceeds the 40-character SHA-1 standard
  • 64 characters matches SHA-256 specification (future preparation)
    [analysis]
    FINDING: The MAX_SHA_LENGTH = 64 does NOT align with GitHub API current behavior
  • GitHub API returns SHA-1 hashes (40 characters max)
  • Setting field to 64 is over-provisioned
  • This appears intentional (preparing for SHA-256 migration) but not aligned with current reality
  • The original review comment asked to "verify that the database field and GitHub API responses align with the 64-character limit"
  • VERDICT: They do NOT align - GitHub API returns 40-char SHAs, not 64-char

The original review was actually requesting verification that contradicts what the code does.
The code is not "wrong" per se - it's conservative/forward-compatible - but the original verification request was mis-stated.

DECISION: This is a case where the original review comment's concern is technically valid but not critical:

  1. The constants are well-defined
  2. The database schema is consistent
  3. The field can store GitHub API responses (40 chars < 64 chars capacity)
  4. The extra capacity is unusual but not problematic

Should tag this as because while verification confirms the mismatch noted in the original request, this is not a functional issue. The database will work correctly with current GitHub API.

Actually, re-reading the original comment more carefully, it says "If MAX_SHA_LENGTH = 64 was the original value, this refactor correctly preserves the existing behavior" with a tag of . This means the original reviewer was actually approving the code IF it was preserving existing behavior.

But the original also asks to "Verify that the database field and GitHub API responses align with the 64-character limit" - which they don't. The API returns 40-char values, not 64-char.

This is a borderline case. The constants are correct and don't need fixing. The verification found they're misaligned with GitHub API spec, but not in a way that breaks the code.

Final judgment: - flag for developer to confirm this over-provisioning is intentional
[done]
</scratchpad_start] -->

Verify the reasoning behind MAX_SHA_LENGTH = 64.

GitHub API returns full, 40-character SHA-1 hashes for commits, but your code sets MAX_SHA_LENGTH = 64. Git's SHA-1 hash algorithm generates a 160-bit (20-byte) hash value, commonly expressed as a 40-character hexadecimal number. The 64-character capacity appears to prepare for SHA-256 migration rather than match current GitHub API responses.

The constant definitions are well-formed and consistent with the database schema. However, confirm with your team whether intentionally over-provisioning the SHA field is acceptable, or if it should be set to 40 to match GitHub's specification.

backend/apps/common/utils.py (1)

52-52: Type hint improvements look good but seem out of scope.

The type hint additions (Optional[str], HttpRequest, Iterable[Any], int | str | datetime, Optional[str]) improve type safety and code documentation. However, these changes don't align with the PR's stated objective of extracting magic numbers. Consider whether these type hint improvements should be in a separate PR focused on type safety enhancements.

Can you clarify whether these type hint changes were intentionally included in this PR, or if they should be part of a separate type-safety focused PR?

Also applies to: 91-91, 108-108, 122-122, 142-142, 199-199

Comment on lines +14 to +16
from typing import Optional, Iterable, Any
from django.http import HttpRequest

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Address static analysis hints for import optimization.

The static analysis tools have identified two valid improvements:

  1. Iterable should be imported from collections.abc instead of typing (deprecated as of Python 3.9)
  2. HttpRequest is only used in type annotations and should be moved into a TYPE_CHECKING block to avoid runtime import overhead

Apply this diff to fix the imports:

-from typing import Optional, Iterable, Any
-from django.http import HttpRequest
-
+from collections.abc import Iterable
+from typing import TYPE_CHECKING, Any, Optional
+
+if TYPE_CHECKING:
+    from django.http import HttpRequest

As per static analysis hints.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from typing import Optional, Iterable, Any
from django.http import HttpRequest
from collections.abc import Iterable
from typing import TYPE_CHECKING, Any, Optional
if TYPE_CHECKING:
from django.http import HttpRequest
🧰 Tools
🪛 Ruff (0.14.4)

14-14: Import from collections.abc instead: Iterable

Import from collections.abc

(UP035)


15-15: Move third-party import django.http.HttpRequest into a type-checking block

Move into type-checking block

(TC002)

🤖 Prompt for AI Agents
In backend/apps/common/utils.py around lines 14 to 16, update the imports to
import Iterable from collections.abc and move HttpRequest into a TYPE_CHECKING
block: replace "from typing import Optional, Iterable, Any" with "from typing
import Optional, Any" and add "from collections.abc import Iterable", then wrap
"from django.http import HttpRequest" inside "if TYPE_CHECKING:" after adding
"from typing import TYPE_CHECKING" at the top so HttpRequest is only imported
for type checking and avoids runtime overhead.

@sonarqubecloud
Copy link

@rudransh-shrivastava
Copy link
Collaborator

rudransh-shrivastava commented Nov 17, 2025

Hi @sonu1680, it seems you've updated the PR. Feel free to ping me or request a review when you think it's good to go.
Also, please address all coderabbit comments More Information
Thanks!

@rudransh-shrivastava rudransh-shrivastava self-assigned this Nov 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract Magic Numbers to Named Constants

2 participants