Skip to content

Conversation

@Rajgupta36
Copy link
Collaborator

@Rajgupta36 Rajgupta36 commented Jul 22, 2025

Proposed change

Resolves #1759

description

Created the Task model according to the issue

Checklist

  • Updated Module Model
  • Created Task Model

@Rajgupta36 Rajgupta36 requested a review from arkid15r as a code owner July 22, 2025 18:56
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 22, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a new Task management system for mentorship modules, allowing tracking of tasks, assignment to users, status updates, deadlines, and metadata.
    • Added support for labels on mentorship modules, enabling better categorization and filtering.
  • Improvements

    • Enhanced admin interface for tasks, including advanced search, filtering, and display options for easier task management.

Walkthrough

This change introduces a new Task model to the mentorship app, establishes its Django admin interface, and updates the Module model with a JSON labels field. The database migration reflects these model changes, enabling tracking of mentee progress on GitHub issues, associating tasks with modules, and supporting additional metadata.

Changes

File(s) Change Summary
backend/apps/mentorship/models/task.py Added new Task model with status tracking, foreign keys, deadline, metadata, and string representation.
backend/apps/mentorship/admin.py Registered Task model in Django admin with custom list, search, and filter options.
backend/apps/mentorship/models/module.py Added labels JSONField to Module model; reformatted imports.
backend/apps/mentorship/migrations/0002_module_labels_task.py Migration to add labels to Module and create new Task model with all specified fields and options.

Estimated code review effort

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

Suggested reviewers

  • kasya

Note

⚡️ Unit Test Generation - Beta

CodeRabbit's unit test generation is now available in Beta! Automatically generate comprehensive unit tests for your code changes, ensuring better test coverage and catching edge cases you might miss. Our AI analyzes your code structure and creates tests that follow best practices and your project's testing patterns. Learn more here, or just try it under ✨ Finishing Touches.


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 488731a and 42b0684.

📒 Files selected for processing (2)
  • backend/apps/mentorship/admin.py (2 hunks)
  • backend/apps/mentorship/models/task.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/apps/mentorship/admin.py
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Rajgupta36
PR: OWASP/Nest#1717
File: backend/apps/mentorship/graphql/mutations/module.py:28-29
Timestamp: 2025-07-16T13:49:58.648Z
Learning: In the OWASP Nest mentorship system, mentors can be created with only github_user initially (without nest_user) when assigned to modules. This allows mentors to be assigned before they've signed into the system. When these users eventually sign in, the nest_user is automatically linked to the existing github_user, creating a complete mentor profile. This design provides flexibility in mentor assignment workflows.
backend/apps/mentorship/models/task.py (2)

Learnt from: Rajgupta36
PR: #1717
File: backend/apps/mentorship/graphql/mutations/module.py:28-29
Timestamp: 2025-07-16T13:49:58.648Z
Learning: In the OWASP Nest mentorship system, mentors can be created with only github_user initially (without nest_user) when assigned to modules. This allows mentors to be assigned before they've signed into the system. When these users eventually sign in, the nest_user is automatically linked to the existing github_user, creating a complete mentor profile. This design provides flexibility in mentor assignment workflows.

Learnt from: Rajgupta36
PR: #1717
File: frontend/src/app/mentorship/programs/page.tsx:14-14
Timestamp: 2025-07-13T11:34:31.823Z
Learning: In the Next.js frontend mentorship application, there are two distinct types for authentication-related data: ExtendedSession for useSession hook (containing accessToken and user.login properties) and UserRolesData for useUserRoles hook (containing currentUserRoles.roles array). The correct access pattern for GitHub username is (session as ExtendedSession)?.user?.login.

⏰ 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 frontend e2e tests
  • GitHub Check: Run frontend unit tests
  • GitHub Check: Run backend tests
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (5)
backend/apps/mentorship/models/task.py (5)

1-8: LGTM: Clean imports and module structure.

The file structure follows Django conventions with proper future annotations import and clean organization.


10-18: LGTM: Well-configured model Meta class.

The Meta configuration is properly set up with appropriate table name, verbose name, unique constraint, and ordering. The unique constraint on (issue, assignee) prevents duplicate task assignments, which is sensible for this domain.


19-26: LGTM: Comprehensive status enumeration.

The Status enum covers the typical task workflow states and follows Django TextChoices best practices with clear labels.


27-48: LGTM: Well-defined task fields.

The field definitions are appropriate:

  • assigned_at with auto_now_add=True correctly timestamps task assignment
  • deadline_at as optional provides flexibility
  • metadata JSONField with default=dict allows extensibility
  • status field with proper choices and default value

All fields include helpful documentation.


59-71: LGTM: Appropriate foreign key relationships.

The relationships are well-designed:

  • issue uses PROTECT to prevent accidental deletion of referenced GitHub issues
  • module uses CASCADE which makes sense as tasks are owned by modules
  • Related names are descriptive and follow conventions
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
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: 5

🧹 Nitpick comments (2)
backend/apps/mentorship/models/common/status.py (1)

1-1: Fix the incorrect file docstring.

The docstring says "Mentorship app start/end range" but this file defines status choices for tasks.

-"""Mentorship app start/end range."""
+"""Status model for mentorship tasks."""
backend/apps/mentorship/admin.py (1)

102-106: Handle potential null assignee in search fields.

The search field "assignee__github_user__login" could cause issues when tasks have no assignee (assignee is nullable in the Task model). Consider adding error handling or making the search more robust.

Consider using a more defensive search approach or document that searches may not return tasks with null assignees:

search_fields = (
    "issue__title",
    "module__name",
    # Note: This won't find tasks with null assignees
    "assignee__github_user__login",
)

Or implement a custom search method that handles null assignees gracefully.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e609d3e and 579f7fd.

📒 Files selected for processing (6)
  • backend/apps/mentorship/admin.py (2 hunks)
  • backend/apps/mentorship/migrations/0002_module_labels_task.py (1 hunks)
  • backend/apps/mentorship/models/common/__init__.py (1 hunks)
  • backend/apps/mentorship/models/common/status.py (1 hunks)
  • backend/apps/mentorship/models/module.py (2 hunks)
  • backend/apps/mentorship/models/task.py (1 hunks)
🧠 Learnings (2)
📓 Common learnings
Learnt from: Rajgupta36
PR: OWASP/Nest#1717
File: backend/apps/mentorship/graphql/mutations/module.py:28-29
Timestamp: 2025-07-16T13:49:58.648Z
Learning: In the OWASP Nest mentorship system, mentors can be created with only github_user initially (without nest_user) when assigned to modules. This allows mentors to be assigned before they've signed into the system. When these users eventually sign in, the nest_user is automatically linked to the existing github_user, creating a complete mentor profile. This design provides flexibility in mentor assignment workflows.
backend/apps/mentorship/models/common/status.py (1)

Learnt from: Rajgupta36
PR: #1717
File: frontend/src/components/ModuleForm.tsx:112-134
Timestamp: 2025-07-14T16:18:07.287Z
Learning: In the OWASP Nest mentorship system, date validation for modules (ensuring start date precedes end date) is handled on the backend in the module GraphQL mutations via the _validate_module_dates helper function in backend/apps/mentorship/graphql/mutations/module.py, which prevents invalid date ranges from being stored in the database.

🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Rajgupta36
PR: OWASP/Nest#1717
File: backend/apps/mentorship/graphql/mutations/module.py:28-29
Timestamp: 2025-07-16T13:49:58.648Z
Learning: In the OWASP Nest mentorship system, mentors can be created with only github_user initially (without nest_user) when assigned to modules. This allows mentors to be assigned before they've signed into the system. When these users eventually sign in, the nest_user is automatically linked to the existing github_user, creating a complete mentor profile. This design provides flexibility in mentor assignment workflows.
backend/apps/mentorship/models/common/status.py (1)

Learnt from: Rajgupta36
PR: #1717
File: frontend/src/components/ModuleForm.tsx:112-134
Timestamp: 2025-07-14T16:18:07.287Z
Learning: In the OWASP Nest mentorship system, date validation for modules (ensuring start date precedes end date) is handled on the backend in the module GraphQL mutations via the _validate_module_dates helper function in backend/apps/mentorship/graphql/mutations/module.py, which prevents invalid date ranges from being stored in the database.

⏰ 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). (3)
  • GitHub Check: Run CI Denendencies Scan
  • GitHub Check: Run Code Scan
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (11)
backend/apps/mentorship/models/common/__init__.py (1)

4-4: LGTM! Status import follows existing patterns.

The import statement correctly exposes the new Status model from the common models package, maintaining consistency with other imports.

backend/apps/mentorship/admin.py (1)

90-116: Excellent admin configuration implementation.

The TaskAdmin class provides comprehensive management capabilities with appropriate display fields, search functionality, and filtering options. The registration follows Django best practices.

backend/apps/mentorship/models/module.py (2)

8-12: LGTM! Improved import formatting for readability.

The multi-line import format improves code readability and follows Python style guidelines.


49-53: Fix mutable default argument issue.

Using default=list creates a shared mutable object across all model instances, which can lead to unexpected behavior where changes to one instance's labels affect others.

-    labels = models.JSONField(
-        blank=True,
-        default=list,
-        verbose_name="Labels",
-    )
+    labels = models.JSONField(
+        blank=True,
+        default=list,  # This creates a callable that returns a new list
+        verbose_name="Labels",
+    )

Wait, let me reconsider this. In Django models, default=list is actually correct because Django calls the function to create a new list for each instance. However, for clarity and to follow best practices, consider using a lambda:

-        default=list,
+        default=lambda: [],

This makes the intent more explicit.

Likely an incorrect or invalid review comment.

backend/apps/mentorship/models/task.py (3)

12-44: Well-designed model with appropriate relationships.

The Task model effectively connects the key entities (Module, Issue, Mentee) with sensible foreign key relationships and on_delete behaviors. The Meta configuration with unique constraints and ordering is well thought out.


18-18: Please validate that the issue+assignee unique constraint matches your assignment workflows

Our search across the codebase didn’t surface any conflicting patterns or alternate “task”/“assignment” logic that would override or clash with this constraint. Before merging, confirm that your domain allows only one Task per issue-assignee pairing:

• How will you handle reopening a completed task? (update the existing record vs. creating a new one)
• If the same issue needs separate Tasks under different Modules, should Module be part of the uniqueness?
• Do you need to preserve assignment history (e.g., multiple Task records for the same issue and mentee over time)?

File to review:

  • backend/apps/mentorship/models/task.py → Meta.unique_together = ("issue", "assignee")

54-58: Fix mutable default argument in metadata field.

Using default=dict creates a shared mutable object across all model instances, which can lead to unexpected behavior.

-    metadata = models.JSONField(
-        default=dict,
-        blank=True,
-        help_text="Optional data",
-    )
+    metadata = models.JSONField(
+        default=dict,  # Django calls this function for each instance
+        blank=True,
+        help_text="Optional data",
+    )

Actually, similar to the Module model, Django handles this correctly, but for clarity consider:

-        default=dict,
+        default=lambda: {},

Likely an incorrect or invalid review comment.

backend/apps/mentorship/migrations/0002_module_labels_task.py (4)

1-12: Migration structure looks good.

The migration follows Django conventions with proper dependencies and imports.


64-91: Well-designed foreign key relationships.

The foreign key relationships are thoughtfully designed:

  • assignee with SET_NULL allows flexibility for unassigned tasks
  • issue with PROTECT prevents accidental deletion of referenced GitHub issues
  • module with CASCADE ensures proper cleanup when modules are deleted

The related_names and help_text provide good developer experience.


60-62: Fix mutable default for metadata JSONField.

Using default=dict creates a mutable default shared across instances, similar to the labels field issue.

Apply this fix:

-                    models.JSONField(blank=True, default=dict, help_text="Optional data"),
+                    models.JSONField(blank=True, default=dict, help_text="Optional data"),

Likely an incorrect or invalid review comment.


15-19: Fix mutable default for JSONField.

Using default=list creates a mutable default that's shared across all instances, which can lead to unexpected behavior where changes to one instance's labels affect others.

Apply this fix:

-            field=models.JSONField(blank=True, default=list, verbose_name="Labels"),
+            field=models.JSONField(blank=True, default=list, verbose_name="Labels"),

Wait, let me correct that - use a callable default:

-            field=models.JSONField(blank=True, default=list, verbose_name="Labels"),
+            field=models.JSONField(blank=True, default=list, verbose_name="Labels"),

Actually, the proper fix is:

-            field=models.JSONField(blank=True, default=list, verbose_name="Labels"),
+            field=models.JSONField(blank=True, default=list, verbose_name="Labels"),

Likely an incorrect or invalid review comment.

@Rajgupta36 Rajgupta36 requested a review from arkid15r July 23, 2025 09:11
@Rajgupta36 Rajgupta36 changed the title Added Task module Added Task model Jul 23, 2025
Copy link
Collaborator

Choose a reason for hiding this comment

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

You don't have to separate it if it's used by only one model.

@Rajgupta36 Rajgupta36 requested a review from arkid15r July 23, 2025 19:54
@sonarqubecloud
Copy link

@arkid15r arkid15r enabled auto-merge July 23, 2025 21:38
@arkid15r arkid15r added this pull request to the merge queue Jul 23, 2025
Merged via the queue into OWASP:main with commit a5b6ff3 Jul 23, 2025
24 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jul 24, 2025
3 tasks
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.

Add Task Model to Track Mentee Progress on GitHub Issues

2 participants