Skip to content

Conversation

@Rajgupta36
Copy link
Collaborator

Proposed change

Resolves #2240

Task

  • create mentee page
  • created menteenode and queries

MEDIA

image image

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 7, 2025

Summary by CodeRabbit

  • New Features
    • Issue comments now synchronized and viewable within the platform
    • Pull requests automatically linked to referenced issues via closing keywords
    • Issues assigned difficulty levels for better categorization
    • Module issue management with label filtering and pagination support
    • Task deadline assignment and tracking for mentee issues
    • Mentee profile pages with contribution tracking and issue assignments
    • Enhanced issue detail views displaying assignees, labels, and related pull requests

Walkthrough

Adds mentorship features and GitHub integrations: new models (Comment, IssueUserInterest), schema/migration changes (issue level, PR–issue M2M), GraphQL node/mutation/query extensions, management commands and Makefile targets, many frontend pages/components/types, and admin updates.

Changes

Cohort / File(s) Summary
Makefiles & build targets
backend/Makefile, backend/apps/mentorship/Makefile, backend/apps/github/Makefile
Include mentorship Makefile; add mentorship and github Make targets for syncing modules/levels/comments and updating PR→issue links.
Models & migrations (github)
backend/apps/github/models/comment.py, backend/apps/github/models/issue.py, backend/apps/github/models/pull_request.py, backend/apps/github/migrations/0037_issue_level_comment.py, backend/apps/github/migrations/0038_pullrequest_related_issues.py, backend/apps/github/models/__init__.py
Add Comment model (generic relation), Issue.level FK and comments relation, PullRequest.related_issues M2M, exports updated.
Models & migrations (mentorship)
backend/apps/mentorship/models/module.py, backend/apps/mentorship/models/task.py, backend/apps/mentorship/models/issue_user_interest.py, backend/apps/mentorship/migrations/0005_remove_task_level_module_issues_and_more.py, backend/apps/mentorship/models/__init__.py
Add Module.issues M2M, remove Task.level, make Task.assigned_at nullable, add IssueUserInterest model, export updates.
Backend admin
backend/apps/github/admin/*.py, backend/apps/mentorship/admin/*.py, backend/apps/github/admin/__init__.py, backend/apps/mentorship/admin/__init__.py
New/admin updates: CommentAdmin, add IssueAdmin list_display level, PullRequestAdmin autocomplete related_issues; mentorship admin UIs added/adjusted (mentee module, issue user interest, module/task tweaks).
GraphQL (backend)
backend/apps/github/api/internal/nodes/issue.py, backend/apps/github/api/internal/nodes/pull_request.py, backend/apps/mentorship/api/internal/nodes/*, backend/apps/mentorship/api/internal/mutations/module.py, backend/apps/mentorship/api/internal/queries/mentorship.py
Extend IssueNode and PullRequestNode fields; add MenteeNode, extend ModuleNode with labels/mentees/issues and many resolvers; add mutations for assign/unassign and set/clear deadlines; add queries for mentee details and mentee module issues.
Management commands & sync logic
backend/apps/github/common.py, backend/apps/github/management/commands/github_update_pull_requests.py, backend/apps/mentorship/management/commands/*.py
Add sync_issue_comments, github_update_pull_requests command; mentorship commands: mentorship_update_comments, sync_module_issues, sync_issue_levels.
Mentorship managers & utils
backend/apps/mentorship/models/managers/module.py, backend/apps/mentorship/models/managers/__init__.py, backend/apps/mentorship/utils.py
Add PublishedModuleManager and normalize_name utility; re-export manager.
Frontend types & queries
frontend/src/types/*, frontend/src/server/queries/*, frontend/src/server/mutations/moduleMutations.ts
Add/adjust Issue, PullRequest, Module, mentorship and card types; add GET_MODULE_ISSUE_VIEW, module/mentee/issue queries and related mutations; include labels/mentees in module mutations.
Frontend components & pages
frontend/src/components/* (LabelList, MenteeContributorsList, MenteeIssues, CardDetailsPage, ModuleCard, ModuleForm, ProgramCard, SingleModuleCard), frontend/src/hooks/useIssueMutations.ts, frontend/src/app/my/mentorship/... (issues page, issue detail, mentee profile, module pages, create/edit)
New UI components for labels/mentees/issues, hook for issue mutations, new pages: module issues list, issue details with deadline/assign actions, mentee profile; DetailsCard wiring updated to accept labels/mentees.
Tests & mocks
backend/tests/..., frontend/__tests__/*, frontend/__tests__/unit/data/*
Update GraphQL node tests and numerous frontend unit tests/mock data to include new fields (PR id/state/mergedAt, module labels, etc.).
Misc
cspell/custom-dict.txt, small UI tweaks
Added dictionary entries; minor component tweaks (title casing change, tooltip class removal).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas to focus review on:

  • Backend migrations and model relationships (github Comment, Issue.level, PR.related_issues; mentorship IssueUserInterest and Module.issues).
  • GraphQL schema/mutation additions (resolver DB queries, permission checks, timezone/deadline logic).
  • Management commands that perform bulk DB changes or GitHub API interactions.
  • Frontend pages with new data flows (issues list, issue detail, mentee profile) and the useIssueMutations hook.
  • Tests/mocks alignment with new types and fields.

Possibly related PRs

Suggested reviewers

  • arkid15r
  • kasya

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Many changes extend beyond the mentee page feature, including GitHub PR/issue synchronization, comment handling, task deadline management, module labels, and various GraphQL fields that are not directly required by issue #2240. Consider separating concerns into focused PRs: one for mentee page implementation, and separate PRs for GitHub sync features, task deadline management, and module enhancements to improve review clarity.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Feat/mentee page' is concise and directly describes the main feature being implemented, aligning with the PR's primary objective of creating a mentee profile page.
Description check ✅ Passed The description clearly references the linked issue (#2240) and outlines completed tasks (mentee page creation and menteenode/queries), relating to the PR's scope and objectives.
Linked Issues check ✅ Passed The PR implements all scope items from issue #2240: the mentee profile page at the correct path, displays completed levels, penalties, and both open/closed issues with clear distinction.
Docstring Coverage ✅ Passed Docstring coverage is 91.07% 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

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.

@Rajgupta36 Rajgupta36 self-assigned this Nov 7, 2025
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: 10

🧹 Nitpick comments (8)
backend/apps/mentorship/utils.py (1)

4-6: Add type hints for better code clarity.

The function logic is correct, but adding type hints would improve maintainability and provide better IDE support.

Apply this diff to add type hints:

-def normalize_name(name):
-    """Normalize a string by stripping whitespace and converting to lowercase."""
-    return (name or "").strip().casefold()
+def normalize_name(name: str | None) -> str:
+    """Normalize a string by stripping whitespace and converting to lowercase."""
+    return (name or "").strip().casefold()
frontend/src/types/mentorship.ts (1)

111-123: Add missing mentee metadata to the shared type

Line 111: MenteeDetails is exported for reuse, but it currently omits experienceLevel, domains, and tags, even though the new mentee profile page (and the GraphQL query powering it) rely on those fields. Any consumer importing MenteeDetails will immediately hit type errors when attempting to read the same properties that the UI already uses. Please align the type with the API response.

 export type MenteeDetails = {
   id: string
   login: string
   name: string
   avatarUrl: string
   email?: string
   bio?: string
+  experienceLevel: ExperienceLevelEnum
+  domains?: string[]
+  tags?: string[]
   completedLevels: CompletedLevel[]
   achievements: Achievement[]
   penalties: Penalty[]
   openIssues: Issue[]
   closedIssues: Issue[]
 }
backend/apps/github/common.py (1)

237-299: Review the since timestamp logic.

The since calculation (lines 257-261) assumes that if issue.latest_comment exists, either updated_at or created_at will be non-None. If both are None, since would be None, which is acceptable as the code handles this case by fetching all comments (line 265).

However, consider adding a comment explaining this fallback behavior for clarity.

Consider adding a brief comment:

 since = (
     (issue.latest_comment.updated_at or issue.latest_comment.created_at)
     if issue.latest_comment
     else getattr(issue, "updated_at", None)
 )
+# If since is None, fetch all comments (no date filter)
backend/apps/mentorship/admin/issue_user_interest.py (1)

11-11: Consider adding user to list_display.

The admin interface allows searching by user__login but doesn't display the user in the list. Adding "user" to list_display would improve visibility and make it easier to identify which users are interested in specific issues.

Apply this diff:

-    list_display = ("module", "issue")
+    list_display = ("module", "issue", "user")
backend/apps/mentorship/models/module.py (1)

20-21: Explicit objects manager is unnecessary.

Django automatically provides a default objects manager. Explicitly declaring it is redundant unless you're overriding it with custom behavior.

Remove the explicit declaration:

-    objects = models.Manager()
     published_modules = PublishedModuleManager()
backend/apps/github/admin/comment.py (1)

11-16: Consider truncating comment body in list display.

Displaying the full body field in list_display may result in very long rows for lengthy comments. Consider using a custom method that truncates the body for better readability in the admin list view.

Add a custom display method:

+    def short_body(self, obj):
+        """Display truncated body for list view."""
+        return obj.body[:75] + "..." if len(obj.body) > 75 else obj.body
+    short_body.short_description = "Body"
+
     list_display = (
-        "body",
+        "short_body",
         "author",
         "nest_created_at",
         "nest_updated_at",
     )
frontend/src/components/MenteeContributorsList.tsx (1)

53-55: Prefer stable keys tied to contributor identity. Using the array index as the key makes React diffing fragile when the list changes (e.g., contributors added/removed or re-ordered). Switching to a stable identifier like the mentee login keeps re-renders predictable.

-        {displayContributors.map((item, index) => (
-          <div key={index} className="overflow-hidden rounded-lg bg-gray-200 p-4 dark:bg-gray-700">
+        {displayContributors.map((item) => (
+          <div key={item.login} className="overflow-hidden rounded-lg bg-gray-200 p-4 dark:bg-gray-700">
backend/apps/mentorship/models/issue_user_interest.py (1)

9-14: Replace deprecated unique_together with UniqueConstraint.

Line 13 still relies on unique_together, which Django 5.0 deprecates; new models should prefer models.UniqueConstraint so we don’t inherit warnings on the next framework upgrade. Update the Meta constraints instead of relying on the legacy setting.

Here’s a minimal swap:

 class Meta:
-        db_table = "mentorship_issue_user_interests"
-        verbose_name = "Issue User Interest"
-        verbose_name_plural = "Issue User Interests"
-        unique_together = ("module", "issue", "user")
+        db_table = "mentorship_issue_user_interests"
+        verbose_name = "Issue User Interest"
+        verbose_name_plural = "Issue User Interests"
+        constraints = [
+            models.UniqueConstraint(
+                fields=("module", "issue", "user"),
+                name="unique_issue_interest",
+            )
+        ]
📜 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 e49e117 and d760622.

⛔ Files ignored due to path filters (6)
  • frontend/src/types/__generated__/graphql.ts is excluded by !**/__generated__/**
  • frontend/src/types/__generated__/issueQueries.generated.ts is excluded by !**/__generated__/**
  • frontend/src/types/__generated__/menteeQueries.generated.ts is excluded by !**/__generated__/**
  • frontend/src/types/__generated__/moduleMutations.generated.ts is excluded by !**/__generated__/**
  • frontend/src/types/__generated__/moduleQueries.generated.ts is excluded by !**/__generated__/**
  • frontend/src/types/__generated__/programsQueries.generated.ts is excluded by !**/__generated__/**
📒 Files selected for processing (72)
  • backend/Makefile (1 hunks)
  • backend/apps/github/Makefile (1 hunks)
  • backend/apps/github/admin/__init__.py (1 hunks)
  • backend/apps/github/admin/comment.py (1 hunks)
  • backend/apps/github/admin/issue.py (1 hunks)
  • backend/apps/github/admin/pull_request.py (1 hunks)
  • backend/apps/github/api/internal/nodes/issue.py (3 hunks)
  • backend/apps/github/api/internal/nodes/pull_request.py (1 hunks)
  • backend/apps/github/common.py (2 hunks)
  • backend/apps/github/management/commands/github_update_pull_requests.py (1 hunks)
  • backend/apps/github/migrations/0037_issue_level_comment.py (1 hunks)
  • backend/apps/github/migrations/0038_pullrequest_related_issues.py (1 hunks)
  • backend/apps/github/models/__init__.py (1 hunks)
  • backend/apps/github/models/comment.py (1 hunks)
  • backend/apps/github/models/issue.py (3 hunks)
  • backend/apps/github/models/pull_request.py (1 hunks)
  • backend/apps/mentorship/Makefile (1 hunks)
  • backend/apps/mentorship/admin/__init__.py (1 hunks)
  • backend/apps/mentorship/admin/issue_user_interest.py (1 hunks)
  • backend/apps/mentorship/admin/mentee_module.py (1 hunks)
  • backend/apps/mentorship/admin/module.py (1 hunks)
  • backend/apps/mentorship/admin/task.py (1 hunks)
  • backend/apps/mentorship/api/internal/mutations/module.py (6 hunks)
  • backend/apps/mentorship/api/internal/nodes/mentee.py (1 hunks)
  • backend/apps/mentorship/api/internal/nodes/module.py (5 hunks)
  • backend/apps/mentorship/api/internal/queries/mentorship.py (2 hunks)
  • backend/apps/mentorship/management/commands/mentorship_update_comments.py (1 hunks)
  • backend/apps/mentorship/management/commands/sync_issue_levels.py (1 hunks)
  • backend/apps/mentorship/management/commands/sync_module_issues.py (1 hunks)
  • backend/apps/mentorship/migrations/0005_remove_task_level_module_issues_and_more.py (1 hunks)
  • backend/apps/mentorship/models/__init__.py (1 hunks)
  • backend/apps/mentorship/models/issue_user_interest.py (1 hunks)
  • backend/apps/mentorship/models/managers/__init__.py (1 hunks)
  • backend/apps/mentorship/models/managers/module.py (1 hunks)
  • backend/apps/mentorship/models/module.py (2 hunks)
  • backend/apps/mentorship/models/task.py (1 hunks)
  • backend/apps/mentorship/utils.py (1 hunks)
  • backend/tests/apps/github/api/internal/nodes/issue_test.py (1 hunks)
  • backend/tests/apps/github/api/internal/nodes/pull_request_test.py (1 hunks)
  • cspell/custom-dict.txt (2 hunks)
  • frontend/__tests__/unit/components/CardDetailsPage.test.tsx (2 hunks)
  • frontend/__tests__/unit/components/ItemCardList.test.tsx (2 hunks)
  • frontend/__tests__/unit/components/RecentPullRequests.test.tsx (1 hunks)
  • frontend/__tests__/unit/components/SingleModuleCard.test.tsx (1 hunks)
  • frontend/__tests__/unit/data/mockOrganizationData.ts (2 hunks)
  • frontend/__tests__/unit/data/mockProjectDetailsData.ts (2 hunks)
  • frontend/__tests__/unit/data/mockRepositoryData.ts (2 hunks)
  • frontend/__tests__/unit/data/mockUserDetails.ts (1 hunks)
  • frontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx (2 hunks)
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/edit/page.tsx (2 hunks)
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/[issueId]/page.tsx (1 hunks)
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/page.tsx (1 hunks)
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeHandle]/page.tsx (1 hunks)
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx (2 hunks)
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/create/page.tsx (2 hunks)
  • frontend/src/components/CardDetailsPage.tsx (5 hunks)
  • frontend/src/components/LabelList.tsx (1 hunks)
  • frontend/src/components/MenteeContributorsList.tsx (1 hunks)
  • frontend/src/components/MenteeIssues.tsx (1 hunks)
  • frontend/src/components/ModuleCard.tsx (3 hunks)
  • frontend/src/components/ModuleForm.tsx (2 hunks)
  • frontend/src/components/ProgramCard.tsx (0 hunks)
  • frontend/src/components/SingleModuleCard.tsx (2 hunks)
  • frontend/src/hooks/useIssueMutations.ts (1 hunks)
  • frontend/src/server/mutations/moduleMutations.ts (2 hunks)
  • frontend/src/server/queries/issueQueries.ts (1 hunks)
  • frontend/src/server/queries/menteeQueries.ts (1 hunks)
  • frontend/src/server/queries/moduleQueries.ts (4 hunks)
  • frontend/src/types/card.ts (1 hunks)
  • frontend/src/types/issue.ts (2 hunks)
  • frontend/src/types/mentorship.ts (2 hunks)
  • frontend/src/types/pullRequest.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • frontend/src/components/ProgramCard.tsx
🧰 Additional context used
🧠 Learnings (15)
📚 Learning: 2025-08-31T13:47:15.861Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2155
File: frontend/src/server/queries/programsQueries.ts:81-81
Timestamp: 2025-08-31T13:47:15.861Z
Learning: In frontend/src/server/queries/programsQueries.ts, GET_PROGRAM_DETAILS is actively used in frontend/src/app/my/mentorship/programs/[programKey]/edit/page.tsx for program editing functionality and cannot be removed. It serves a different purpose than GET_PROGRAM_ADMIN_DETAILS, providing comprehensive program information needed for editing.

Applied to files:

  • frontend/src/server/queries/menteeQueries.ts
  • frontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/page.tsx
  • frontend/src/server/queries/issueQueries.ts
  • frontend/src/server/queries/moduleQueries.ts
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/[issueId]/page.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/create/page.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeHandle]/page.tsx
  • frontend/src/components/CardDetailsPage.tsx
  • backend/apps/mentorship/api/internal/queries/mentorship.py
📚 Learning: 2025-08-31T13:47:15.861Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2155
File: frontend/src/server/queries/programsQueries.ts:81-81
Timestamp: 2025-08-31T13:47:15.861Z
Learning: In frontend/src/server/queries/programsQueries.ts, GET_PROGRAM_DETAILS and GET_PROGRAM_ADMIN_DETAILS are two separate queries serving different purposes: GET_PROGRAM_DETAILS fetches comprehensive program information while GET_PROGRAM_ADMIN_DETAILS fetches only admin-related details. These queries cannot be removed or merged as they serve different use cases in the application.

Applied to files:

  • frontend/src/server/queries/menteeQueries.ts
  • frontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx
  • frontend/src/server/queries/issueQueries.ts
  • frontend/src/server/queries/moduleQueries.ts
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx
📚 Learning: 2025-08-31T13:47:15.861Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2155
File: frontend/src/server/queries/programsQueries.ts:81-81
Timestamp: 2025-08-31T13:47:15.861Z
Learning: In frontend/src/server/queries/programsQueries.ts, GET_PROGRAM_DETAILS and GET_PROGRAM_ADMIN_DETAILS are two separate queries serving different purposes: GET_PROGRAM_DETAILS fetches comprehensive program information while GET_PROGRAM_ADMIN_DETAILS fetches only admin-related details.

Applied to files:

  • frontend/src/server/queries/menteeQueries.ts
  • frontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx
  • frontend/src/server/queries/issueQueries.ts
  • frontend/src/server/queries/moduleQueries.ts
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx
📚 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:

  • frontend/src/server/queries/menteeQueries.ts
  • frontend/src/server/queries/moduleQueries.ts
  • backend/apps/mentorship/api/internal/queries/mentorship.py
  • backend/apps/mentorship/api/internal/mutations/module.py
  • backend/apps/mentorship/api/internal/nodes/module.py
  • backend/apps/mentorship/api/internal/nodes/mentee.py
  • backend/apps/github/api/internal/nodes/issue.py
📚 Learning: 2025-09-29T06:02:35.566Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/components/SingleModuleCard.tsx:54-54
Timestamp: 2025-09-29T06:02:35.566Z
Learning: In the Module type from types/mentorship.ts, the experienceLevel field is required (experienceLevel: ExperienceLevelEnum), not optional, so null/undefined checks are not needed when accessing this field.

Applied to files:

  • frontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx
  • frontend/__tests__/unit/components/SingleModuleCard.test.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/create/page.tsx
  • frontend/src/types/mentorship.ts
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/edit/page.tsx
📚 Learning: 2025-07-13T07:31:06.511Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/components/ModuleCard.tsx:53-55
Timestamp: 2025-07-13T07:31:06.511Z
Learning: In Next.js 13+ app router, useRouter from 'next/navigation' does not provide asPath or query properties. Use useParams to extract route parameters and usePathname to get the current pathname instead.

Applied to files:

  • frontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx
  • frontend/src/components/ModuleCard.tsx
📚 Learning: 2025-07-13T11:29:25.245Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/page.tsx:59-61
Timestamp: 2025-07-13T11:29:25.245Z
Learning: In Next.js 13+ app router, components with the 'use client' directive run entirely on the client side and don't require window object existence checks or SSR hydration considerations. Direct access to window.location and other browser APIs is safe in client components.

Applied to files:

  • frontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx
📚 Learning: 2025-07-12T17:14:28.536Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/[programKey]/edit/page.tsx:90-128
Timestamp: 2025-07-12T17:14:28.536Z
Learning: Both ProgramForm (programCard.tsx) and ModuleForm (mainmoduleCard.tsx) components already implement HTML validation using the `required` attribute on form fields. The browser's native validation prevents form submission and displays error messages when required fields are empty, eliminating the need for additional JavaScript validation before GraphQL mutations.

Applied to files:

  • frontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/create/page.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/edit/page.tsx
  • frontend/src/components/ModuleForm.tsx
📚 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/apps/mentorship/Makefile
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a length check before rendering HealthMetrics: `healthMetricsData.length > 0`. This ensures that when HealthMetrics is rendered, the data array has at least one element, making accessing data[0] safe within the HealthMetrics component.

Applied to files:

  • frontend/src/types/card.ts
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a safety check that ensures HealthMetrics component is only rendered when healthMetricsData exists and has at least one element: `healthMetricsData && healthMetricsData.length > 0`. This makes accessing data[0] safe within the HealthMetrics component.

Applied to files:

  • frontend/src/types/card.ts
📚 Learning: 2025-08-17T11:55:55.990Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 2000
File: backend/apps/mentorship/management/commands/sync_module_issues.py:109-145
Timestamp: 2025-08-17T11:55:55.990Z
Learning: In the OWASP/Nest mentorship system, tasks are designed to be assigned to only one assignee per issue, even if GitHub issues can have multiple assignees. The sync_module_issues command correctly uses issue.assignees.first() to create one task per issue for the first assignee only.

Applied to files:

  • backend/apps/mentorship/management/commands/sync_issue_levels.py
  • backend/apps/mentorship/management/commands/sync_module_issues.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/mentorship/api/internal/queries/mentorship.py
  • backend/apps/mentorship/api/internal/mutations/module.py
  • backend/apps/mentorship/api/internal/nodes/module.py
  • backend/apps/mentorship/api/internal/nodes/mentee.py
📚 Learning: 2025-07-14T16:18:07.287Z
Learnt from: Rajgupta36
Repo: OWASP/Nest 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.

Applied to files:

  • backend/apps/mentorship/api/internal/mutations/module.py
📚 Learning: 2025-07-08T17:24:36.501Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: backend/apps/mentorship/graphql/mutations/program.py:41-44
Timestamp: 2025-07-08T17:24:36.501Z
Learning: In the mentorship program GraphQL mutations, date validation is handled at the GraphQL schema/node level in the input types (CreateProgramInput, UpdateProgramInput), preventing null values from reaching the mutation logic where date comparisons are performed.

Applied to files:

  • backend/apps/mentorship/api/internal/mutations/module.py
🧬 Code graph analysis (39)
backend/apps/mentorship/models/managers/__init__.py (1)
backend/apps/mentorship/models/managers/module.py (1)
  • PublishedModuleManager (8-13)
frontend/src/hooks/useIssueMutations.ts (1)
frontend/src/server/queries/issueQueries.ts (5)
  • GET_MODULE_ISSUE_VIEW (3-55)
  • ASSIGN_ISSUE_TO_USER (57-73)
  • UNASSIGN_ISSUE_FROM_USER (75-91)
  • SET_TASK_DEADLINE (93-109)
  • CLEAR_TASK_DEADLINE (111-117)
frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/page.tsx (3)
frontend/src/server/queries/moduleQueries.ts (1)
  • GET_MODULE_ISSUES (98-125)
frontend/src/app/global-error.tsx (2)
  • handleAppError (66-86)
  • ErrorDisplay (28-51)
backend/apps/github/api/internal/nodes/issue.py (1)
  • labels (50-52)
frontend/src/components/LabelList.tsx (2)
backend/apps/github/models/label.py (1)
  • Label (9-77)
backend/apps/github/api/internal/nodes/issue.py (1)
  • labels (50-52)
frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/[issueId]/page.tsx (5)
frontend/src/server/queries/issueQueries.ts (1)
  • GET_MODULE_ISSUE_VIEW (3-55)
frontend/src/hooks/useIssueMutations.ts (1)
  • useIssueMutations (18-144)
frontend/src/app/global-error.tsx (1)
  • ErrorDisplay (28-51)
frontend/src/components/MarkdownWrapper.tsx (1)
  • Markdown (4-17)
frontend/src/components/TruncatedText.tsx (1)
  • TruncatedText (3-45)
frontend/src/types/card.ts (1)
frontend/src/types/contributor.ts (1)
  • Contributor (1-8)
frontend/src/app/my/mentorship/programs/[programKey]/modules/create/page.tsx (1)
frontend/src/utils/parser.ts (1)
  • parseCommaSeparated (1-6)
frontend/src/types/mentorship.ts (1)
frontend/src/types/contributor.ts (1)
  • Contributor (1-8)
backend/apps/mentorship/management/commands/mentorship_update_comments.py (6)
backend/apps/common/utils.py (1)
  • truncate (181-193)
backend/apps/github/common.py (1)
  • sync_issue_comments (237-299)
backend/apps/github/models/issue.py (1)
  • Issue (19-234)
backend/apps/mentorship/models/issue_user_interest.py (1)
  • IssueUserInterest (6-31)
backend/apps/mentorship/models/module.py (1)
  • Module (17-104)
backend/apps/github/models/generic_issue_model.py (1)
  • State (18-20)
frontend/src/types/pullRequest.ts (1)
frontend/src/types/user.ts (1)
  • User (10-32)
frontend/src/components/MenteeContributorsList.tsx (1)
frontend/src/types/contributor.ts (1)
  • Contributor (1-8)
backend/apps/mentorship/models/managers/module.py (1)
backend/apps/mentorship/models/program.py (1)
  • ProgramStatus (25-28)
frontend/src/components/MenteeIssues.tsx (1)
frontend/src/utils/dateFormatter.ts (1)
  • formatDate (1-20)
backend/apps/github/admin/__init__.py (1)
backend/apps/github/admin/comment.py (1)
  • CommentAdmin (8-18)
frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeHandle]/page.tsx (2)
frontend/src/server/queries/menteeQueries.ts (1)
  • GET_MODULE_MENTEE_DETAILS (3-35)
frontend/src/app/global-error.tsx (2)
  • handleAppError (66-86)
  • ErrorDisplay (28-51)
frontend/src/components/CardDetailsPage.tsx (2)
backend/apps/github/api/internal/nodes/issue.py (1)
  • labels (50-52)
backend/apps/mentorship/api/internal/nodes/module.py (1)
  • mentees (41-49)
backend/apps/mentorship/models/__init__.py (1)
backend/apps/mentorship/models/issue_user_interest.py (1)
  • IssueUserInterest (6-31)
backend/apps/mentorship/migrations/0005_remove_task_level_module_issues_and_more.py (1)
backend/apps/github/migrations/0037_issue_level_comment.py (1)
  • Migration (7-74)
backend/apps/mentorship/admin/issue_user_interest.py (1)
backend/apps/mentorship/models/issue_user_interest.py (1)
  • IssueUserInterest (6-31)
backend/apps/github/admin/comment.py (1)
backend/apps/github/models/comment.py (1)
  • Comment (11-85)
frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/edit/page.tsx (1)
frontend/src/utils/parser.ts (1)
  • parseCommaSeparated (1-6)
backend/apps/mentorship/admin/mentee_module.py (1)
backend/apps/mentorship/models/mentee_module.py (1)
  • MenteeModule (11-39)
backend/apps/github/models/comment.py (3)
backend/apps/common/models.py (2)
  • BulkSaveModel (10-34)
  • TimestampedModel (37-46)
backend/apps/common/utils.py (1)
  • truncate (181-193)
backend/apps/github/models/issue.py (5)
  • Meta (25-31)
  • from_github (108-147)
  • bulk_save (199-201)
  • update_data (210-234)
  • save (187-196)
backend/apps/mentorship/models/issue_user_interest.py (3)
backend/apps/github/models/issue.py (1)
  • Meta (25-31)
backend/apps/mentorship/models/module.py (1)
  • Meta (23-31)
backend/apps/github/models/common.py (1)
  • title (40-44)
backend/apps/mentorship/management/commands/sync_issue_levels.py (4)
backend/apps/github/models/issue.py (1)
  • Issue (19-234)
backend/apps/github/models/label.py (1)
  • Label (9-77)
backend/apps/mentorship/models/task_level.py (1)
  • TaskLevel (8-61)
backend/apps/mentorship/utils.py (1)
  • normalize_name (4-6)
frontend/src/types/issue.ts (2)
frontend/src/types/pullRequest.ts (1)
  • PullRequest (3-13)
frontend/src/types/user.ts (1)
  • RepositoryDetails (5-8)
backend/apps/github/common.py (5)
backend/apps/github/models/comment.py (3)
  • Comment (11-85)
  • update_data (59-85)
  • bulk_save (54-56)
backend/apps/github/models/issue.py (5)
  • Issue (19-234)
  • latest_comment (99-106)
  • update_data (210-234)
  • save (187-196)
  • bulk_save (199-201)
backend/apps/github/models/repository.py (2)
  • path (154-156)
  • update_data (307-349)
backend/apps/github/models/user.py (3)
  • User (19-159)
  • update_data (130-159)
  • bulk_save (110-112)
backend/apps/common/models.py (1)
  • bulk_save (19-34)
backend/apps/mentorship/admin/__init__.py (2)
backend/apps/mentorship/models/issue_user_interest.py (1)
  • IssueUserInterest (6-31)
backend/apps/mentorship/admin/mentee_module.py (1)
  • MenteeModuleAdmin (9-32)
backend/apps/mentorship/utils.py (1)
backend/apps/mentorship/api/internal/nodes/mentor.py (1)
  • name (18-20)
backend/apps/github/models/__init__.py (2)
backend/apps/github/models/comment.py (1)
  • Comment (11-85)
backend/apps/github/models/label.py (1)
  • Label (9-77)
backend/apps/github/management/commands/github_update_pull_requests.py (1)
backend/apps/github/models/pull_request.py (2)
  • PullRequest (11-152)
  • bulk_save (114-116)
backend/apps/mentorship/api/internal/queries/mentorship.py (7)
frontend/src/types/__generated__/graphql.ts (2)
  • IssueNode (184-202)
  • MenteeNode (211-221)
backend/apps/mentorship/api/internal/nodes/mentee.py (1)
  • MenteeNode (9-29)
backend/apps/mentorship/models/module.py (1)
  • Module (17-104)
backend/apps/mentorship/models/mentee.py (1)
  • Mentee (11-49)
backend/apps/mentorship/models/mentee_module.py (1)
  • MenteeModule (11-39)
backend/apps/mentorship/api/internal/nodes/module.py (1)
  • issues (74-85)
backend/apps/github/api/internal/nodes/issue.py (1)
  • assignees (45-47)
backend/apps/mentorship/api/internal/mutations/module.py (5)
backend/apps/mentorship/models/issue_user_interest.py (1)
  • IssueUserInterest (6-31)
backend/apps/mentorship/models/task.py (1)
  • Task (10-80)
backend/apps/mentorship/api/internal/nodes/module.py (2)
  • ModuleNode (19-157)
  • issues (74-85)
backend/apps/mentorship/models/module.py (2)
  • Module (17-104)
  • save (97-104)
backend/apps/mentorship/models/mentor.py (1)
  • Mentor (11-40)
backend/apps/github/migrations/0037_issue_level_comment.py (1)
backend/apps/mentorship/migrations/0005_remove_task_level_module_issues_and_more.py (1)
  • Migration (7-79)
backend/apps/mentorship/api/internal/nodes/module.py (5)
backend/apps/github/api/internal/nodes/issue.py (3)
  • IssueNode (22-72)
  • labels (50-52)
  • interested_users (60-67)
backend/apps/github/api/internal/queries/user.py (1)
  • user (40-53)
backend/apps/github/models/label.py (1)
  • Label (9-77)
backend/apps/mentorship/models/issue_user_interest.py (1)
  • IssueUserInterest (6-31)
backend/apps/mentorship/models/task.py (1)
  • Task (10-80)
backend/apps/mentorship/management/commands/sync_module_issues.py (5)
backend/apps/github/models/issue.py (2)
  • Issue (19-234)
  • save (187-196)
backend/apps/mentorship/models/module.py (2)
  • Module (17-104)
  • save (97-104)
backend/apps/mentorship/models/task.py (2)
  • Task (10-80)
  • Status (19-25)
backend/apps/mentorship/utils.py (1)
  • normalize_name (4-6)
backend/apps/github/models/repository.py (1)
  • path (154-156)
backend/apps/mentorship/api/internal/nodes/mentee.py (3)
backend/apps/mentorship/api/internal/nodes/enum.py (1)
  • ExperienceLevelEnum (12-18)
frontend/src/types/__generated__/graphql.ts (1)
  • MenteeNode (211-221)
backend/apps/mentorship/api/internal/nodes/mentor.py (3)
  • login (23-25)
  • name (18-20)
  • avatar_url (13-15)
backend/apps/mentorship/models/module.py (2)
backend/apps/mentorship/models/managers/module.py (1)
  • PublishedModuleManager (8-13)
backend/apps/mentorship/api/internal/nodes/module.py (1)
  • issues (74-85)
backend/apps/github/api/internal/nodes/issue.py (2)
backend/apps/github/api/internal/nodes/pull_request.py (1)
  • PullRequestNode (19-44)
backend/apps/mentorship/api/internal/nodes/module.py (1)
  • interested_users (119-129)
🪛 checkmake (0.2.2)
backend/apps/mentorship/Makefile

[warning] 1-1: Missing required phony target "all"

(minphony)


[warning] 1-1: Missing required phony target "clean"

(minphony)


[warning] 1-1: Missing required phony target "test"

(minphony)

⏰ 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 unit tests
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run backend tests
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (48)
cspell/custom-dict.txt (1)

86-86: Dictionary entries are correctly used and placed.

Both menteemodule_set (line 86) and unassigning (line 124) are verified in the codebase:

  • menteemodule_set: Django ORM reverse relation in backend/apps/mentorship/api/internal/nodes/module.py:44
  • unassigning: React state variable used across frontend components in frontend/src/hooks/useIssueMutations.ts and issue management pages

Entries are in correct alphabetical order. No issues detected.

frontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx (1)

4-4: No changes required. The refactoring is correct and consistent.

All ExperienceLevelEnum values are single lowercase words ('beginner', 'intermediate', 'advanced', 'expert'), so upperFirst correctly formats them for display (e.g., 'Beginner', 'Intermediate'). The usage is consistent across similar components (ModuleCard, SingleModuleCard) and aligns with the intentional refactoring pattern in the codebase.

frontend/__tests__/unit/data/mockOrganizationData.ts (1)

79-79: LGTM: Mock data updated to match new type definition.

The addition of id fields to mock pull requests correctly aligns with the expanded PullRequest type that now includes id, state, and mergedAt fields.

Also applies to: 89-89

frontend/__tests__/unit/data/mockRepositoryData.ts (1)

65-65: LGTM: Consistent mock data updates.

Mock pull request data appropriately updated with id fields to match the expanded type definition.

Also applies to: 75-75

frontend/src/components/SingleModuleCard.tsx (1)

48-51: LGTM: Clean implementation of View Issues navigation.

The new admin action for viewing module issues follows the existing pattern established by handleEdit and handleCreate. The implementation properly manages dropdown state and access control.

Also applies to: 119-126

frontend/src/server/queries/moduleQueries.ts (1)

20-25: LGTM: Well-structured query expansions.

The additions properly support the mentee profile page requirements:

  • Mentee information added to existing module queries
  • New GET_MODULE_ISSUES query with pagination and filtering
  • Consistent with existing query patterns

Also applies to: 48-53, 75-75, 88-93, 98-125

frontend/src/server/queries/menteeQueries.ts (1)

15-20: Consider pagination for mentee issues.

The hardcoded limit of 50 issues may be insufficient for active mentees. If a mentee has more than 50 issues, the remaining issues won't be displayed.

Consider whether:

  1. 50 issues is a reasonable maximum for the mentee profile page requirements
  2. Pagination should be added similar to GET_MODULE_ISSUES (with offset parameter)

If the acceptance criteria require displaying "all issues for the user," pagination or a higher limit may be necessary.

frontend/src/types/pullRequest.ts (1)

4-4: LGTM: Type definition properly extended.

The new fields (id, state, mergedAt) align with the backend GraphQL schema updates and are correctly reflected in test data across the codebase.

Also applies to: 11-12

frontend/__tests__/unit/data/mockProjectDetailsData.ts (1)

104-104: LGTM: Mock data consistently updated.

Pull request mock data properly includes the new id field, maintaining consistency with the updated PullRequest type.

Also applies to: 114-114

backend/apps/github/admin/__init__.py (1)

3-3: LGTM!

The CommentAdmin import follows the existing pattern and maintains alphabetical ordering.

backend/Makefile (1)

3-3: LGTM!

The mentorship Makefile inclusion maintains alphabetical order and enables mentorship-specific Make targets.

frontend/__tests__/unit/components/RecentPullRequests.test.tsx (2)

43-43: LGTM!

The added fields (id, state, mergedAt) align with the updated PullRequest type definition and use appropriate test values.

Also applies to: 50-51


57-57: LGTM!

The test fixture updates maintain consistency with the minimalData fixture and the updated PullRequest type.

Also applies to: 64-65

backend/tests/apps/github/api/internal/nodes/issue_test.py (1)

19-31: LGTM!

The updated expected field names correctly reflect the new fields added to IssueNode (number, body, assignees, labels, is_merged, interested_users, pull_requests).

backend/apps/github/admin/issue.py (1)

22-22: LGTM!

Adding the level field to the admin list display properly exposes the new TaskLevel relationship for mentorship tracking.

backend/apps/mentorship/models/__init__.py (1)

1-1: LGTM!

The IssueUserInterest import follows the standard Django pattern for package-level model exports and maintains alphabetical ordering.

backend/tests/apps/github/api/internal/nodes/pull_request_test.py (1)

20-20: LGTM!

The added fields (merged_at, state) correctly reflect the expanded PullRequestNode schema for GitHub pull request tracking.

Also applies to: 23-23

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

28-28: No changes required; code handles null ordering appropriately.

The ordering = ["-assigned_at"] configuration is correct. PostgreSQL places NULLS FIRST for DESC ordering, which will put tasks with null assigned_at at the top of the admin list—predictable and database-defined behavior. The nullable field and admin ordering configuration work as expected without requiring explicit null handling configuration.

frontend/src/components/ModuleCard.tsx (2)

11-11: LGTM! Correct use of Next.js 13+ app router.

The use of usePathname from next/navigation is the proper approach for obtaining the current pathname in Next.js 13+ app router, replacing the previous reliance on window.location. Based on learnings.

Also applies to: 73-73, 77-77


89-93: LGTM! Clean integration of label display.

The conditional rendering of LabelList with maxVisible={3} is appropriate for the card layout and provides a good UX by limiting visual clutter while still showing relevant labels.

frontend/__tests__/unit/data/mockUserDetails.ts (1)

48-48: LGTM! Test data aligned with updated types.

Adding the id field to the mock pull request aligns with the updated PullRequest type that now includes id, state, and mergedAt fields.

frontend/src/app/my/mentorship/programs/[programKey]/modules/create/page.tsx (1)

42-42: LGTM! Consistent labels handling.

The labels field is properly initialized in the form state and parsed using parseCommaSeparated before mutation, following the same pattern as domains and tags. This maintains consistency across the module creation flow.

Also applies to: 92-92

frontend/src/server/mutations/moduleMutations.ts (1)

15-15: LGTM! Mutation responses updated to include labels.

Adding the labels field to both UPDATE_MODULE and CREATE_MODULE mutation selection sets ensures the frontend receives the complete module data including labels after mutations, maintaining consistency with the backend schema.

Also applies to: 39-39

backend/apps/mentorship/models/managers/__init__.py (1)

1-1: LGTM! Clean manager exposure.

Exposing PublishedModuleManager through the package __init__.py follows standard Django patterns and enables clean usage of the published_modules manager for filtering modules by published program status.

frontend/__tests__/unit/components/ItemCardList.test.tsx (1)

151-151: LGTM! Test mock updated for expanded PullRequest type.

The mock pull request now includes the new fields (id, state, mergedAt) that were added to the PullRequest type, ensuring test data remains consistent with the updated type definitions.

Also applies to: 165-166

frontend/__tests__/unit/components/SingleModuleCard.test.tsx (1)

109-109: LGTM! Test mock extended with labels field.

Adding labels: ['good first issue', 'bug'] to the mock module aligns with the updated Module type that now includes a labels: string[] field, ensuring comprehensive test coverage for the labels feature.

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

16-16: Issue admin search_fields verified—autocomplete will function correctly.

The Issue admin at backend/apps/github/admin/issue.py has search_fields = ("title",) properly configured. The autocomplete functionality for linking issues to modules will work as intended.

frontend/__tests__/unit/components/CardDetailsPage.test.tsx (2)

497-497: LGTM: Field rename aligns with GitHub API terminology.

The change from summary to body correctly matches GitHub's Issue API structure, where issues have a body field rather than a summary field.


521-528: LGTM: PR mock data extended to match type definitions.

The addition of id, state, and mergedAt fields to the mock pull request data aligns with the expanded PullRequestNode GraphQL type and frontend type definitions.

backend/apps/github/admin/pull_request.py (1)

17-17: LGTM: Admin autocomplete properly configured for new relationship.

The addition of related_issues to autocomplete_fields correctly enables the Django admin autocomplete interface for the new ManyToMany relationship between PullRequest and Issue.

frontend/src/components/ModuleForm.tsx (2)

19-19: LGTM: Labels field added to form data interface.

The labels field is properly typed as a string and follows the established pattern for comma-separated input fields like domains and tags.


189-202: LGTM: Labels input field properly integrated.

The new labels input field:

  • Follows the same UI/UX pattern as the existing domains and tags fields
  • Uses the existing handleInputChange handler for state management
  • Provides helpful placeholder text indicating the expected format
  • Correctly positioned in the Additional Details section

Based on learnings.

backend/apps/github/Makefile (1)

21-23: LGTM: New Makefile target follows established patterns.

The github-update-pull-requests target is properly implemented:

  • Follows the same pattern as existing targets (e.g., github-update-users)
  • Provides clear descriptive echo message
  • Uses the standard exec-backend-command mechanism
backend/apps/mentorship/admin/__init__.py (2)

3-3: LGTM: IssueUserInterest admin import added.

The import properly exposes the admin interface for the IssueUserInterest model, which tracks user interest in issues within mentorship modules.


5-5: LGTM: MenteeModuleAdmin import added.

The import properly exposes the admin interface for the MenteeModule model, enabling management of mentee-module relationships through Django admin.

backend/apps/github/models/__init__.py (1)

3-4: LGTM: New model exports properly added.

The Comment and Label model exports extend the public API surface of the github.models package, enabling proper integration of GitHub comments and labels throughout the codebase.

backend/apps/github/api/internal/nodes/pull_request.py (1)

15-16: LGTM: GraphQL node extended with PR state fields.

The addition of state and merged_at fields to the PullRequestNode properly exposes essential pull request information to the GraphQL API, enabling frontend consumers to display PR status and merge timestamps.

backend/apps/github/migrations/0038_pullrequest_related_issues.py (1)

1-19: LGTM: Migration properly implements PR-to-Issue relationship.

The migration correctly adds a ManyToMany relationship between PullRequest and Issue:

  • Proper dependency chain on the prior migration
  • Appropriate use of blank=True to make the relationship optional
  • Clear verbose_name ("Issues") for admin interface
  • Sensible related_name ("pull_requests") for reverse lookups from Issue

This enables tracking which issues are referenced/closed by each pull request, supporting the mentorship workflow.

frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/edit/page.tsx (2)

85-85: LGTM!

The labels field initialization follows the same pattern as domains and tags, correctly handling null/undefined values.


107-107: LGTM!

The labels field submission correctly uses parseCommaSeparated to convert the comma-separated string back to an array, consistent with the handling of domains and tags.

frontend/src/types/card.ts (1)

52-52: LGTM!

The addition of optional labels and mentees fields to DetailsCardProps is correct and maintains backward compatibility while extending the interface to support the mentee profile page requirements.

Also applies to: 58-58

backend/apps/github/common.py (3)

7-7: LGTM!

The use of TYPE_CHECKING to conditionally import Github for type hints is correct and prevents unnecessary runtime imports.

Also applies to: 12-14


268-271: LGTM!

The handling of missing authors (logging a warning and skipping the comment) is appropriate and prevents data integrity issues.


281-287: LGTM!

The use of bulk_save for comments is efficient and the logging provides good visibility into sync operations.

frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx (2)

16-16: LGTM!

Adding explicit type annotation for useParams improves type safety.


68-68: LGTM!

The addition of labels, mentees, programKey, and entityKey props correctly extends the DetailsCard usage to support the mentee profile page requirements.

Also applies to: 71-71, 74-75

backend/apps/github/models/pull_request.py (1)

64-69: The related_issues field is properly populated.

Verification confirms that the field is actively populated in backend/apps/github/management/commands/github_update_pull_requests.py (line 49), where a management command adds related issues via pr.related_issues.add(). The implementation correctly establishes these relationships.

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

72-78: Label matching logic confirmed—no issues with the model field.

The sync_module_issues management command implements label matching and populates the issues field via module.issues.set(matched_issue_ids) at line 115. The command normalizes label names and matches them against issues in project repositories, making the help text accurate. The logic is complete and functional.

Ensure this command is part of your deployment or operations workflow so the M2M relationship is periodically synced.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Nov 7, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

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)
frontend/src/types/mentorship.ts (1)

82-82: Move import statement to the top of the file.

The import statement for Issue is placed after existing type definitions. Following TypeScript/ES6 conventions, all imports should be grouped at the top of the file (near line 1) for better code organization and maintainability.

Apply this diff to move the import to the top:

 import type { Contributor } from 'types/contributor'
+import type { Issue } from 'types/issue'
 export enum ExperienceLevelEnum {

And remove it from line 82:

   labels: string
   projectName: string
   projectId: string
   mentorLogins: string
 }
-
-import type { Issue } from 'types/issue'
-
 export type CompletedLevel = {
📜 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 d760622 and 4bc7c49.

📒 Files selected for processing (2)
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeHandle]/page.tsx (1 hunks)
  • frontend/src/types/mentorship.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeHandle]/page.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-29T06:02:35.566Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/components/SingleModuleCard.tsx:54-54
Timestamp: 2025-09-29T06:02:35.566Z
Learning: In the Module type from types/mentorship.ts, the experienceLevel field is required (experienceLevel: ExperienceLevelEnum), not optional, so null/undefined checks are not needed when accessing this field.

Applied to files:

  • frontend/src/types/mentorship.ts
🧬 Code graph analysis (1)
frontend/src/types/mentorship.ts (1)
frontend/src/types/contributor.ts (1)
  • Contributor (1-8)
⏰ 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 frontend unit tests
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run backend tests
🔇 Additional comments (3)
frontend/src/types/mentorship.ts (3)

60-60: LGTM! Module type enhancements look good.

The additions of mentees (optional) and labels (required array) appropriately extend the Module type to support mentee tracking and module categorization, aligning with the mentorship portal requirements.

Also applies to: 65-65


76-76: LGTM! Consistent with existing form data patterns.

The labels: string field follows the same pattern as domains and tags in ModuleFormData, where form input is captured as a string and later transformed to an array in the Module type.


84-125: LGTM! Comprehensive type definitions align with PR objectives.

The new types (CompletedLevel, Achievement, Penalty, and MenteeDetails) comprehensively cover all requirements from issue #2240:

  • ✓ Completed levels with task/stack information
  • ✓ Achievements tracking
  • ✓ Penalties tracking
  • ✓ Separate open and closed issues lists

All array fields in MenteeDetails are required (not optional), which is appropriate since empty arrays serve as valid defaults when data is absent. The type structure properly supports the acceptance criteria for rendering mentee progress, distinguishing between open/closed issues, and displaying penalties.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant