-
-
Notifications
You must be signed in to change notification settings - Fork 268
Feat/mentee page #2567
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feature/mentorship-portal
Are you sure you want to change the base?
Feat/mentee page #2567
Conversation
Summary by CodeRabbit
WalkthroughAdds 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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Areas to focus review on:
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this 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 typeLine 111:
MenteeDetailsis exported for reuse, but it currently omitsexperienceLevel,domains, andtags, even though the new mentee profile page (and the GraphQL query powering it) rely on those fields. Any consumer importingMenteeDetailswill 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 thesincetimestamp logic.The
sincecalculation (lines 257-261) assumes that ifissue.latest_commentexists, eitherupdated_atorcreated_atwill be non-None. If both are None,sincewould 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 addingusertolist_display.The admin interface allows searching by
user__loginbut doesn't display the user in the list. Adding"user"tolist_displaywould 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: Explicitobjectsmanager is unnecessary.Django automatically provides a default
objectsmanager. 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
bodyfield inlist_displaymay 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 deprecatedunique_togetherwithUniqueConstraint.Line 13 still relies on
unique_together, which Django 5.0 deprecates; new models should prefermodels.UniqueConstraintso 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
⛔ Files ignored due to path filters (6)
frontend/src/types/__generated__/graphql.tsis excluded by!**/__generated__/**frontend/src/types/__generated__/issueQueries.generated.tsis excluded by!**/__generated__/**frontend/src/types/__generated__/menteeQueries.generated.tsis excluded by!**/__generated__/**frontend/src/types/__generated__/moduleMutations.generated.tsis excluded by!**/__generated__/**frontend/src/types/__generated__/moduleQueries.generated.tsis excluded by!**/__generated__/**frontend/src/types/__generated__/programsQueries.generated.tsis excluded by!**/__generated__/**
📒 Files selected for processing (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.tsfrontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsxfrontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/page.tsxfrontend/src/server/queries/issueQueries.tsfrontend/src/server/queries/moduleQueries.tsfrontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/[issueId]/page.tsxfrontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsxfrontend/src/app/my/mentorship/programs/[programKey]/modules/create/page.tsxfrontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeHandle]/page.tsxfrontend/src/components/CardDetailsPage.tsxbackend/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.tsfrontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsxfrontend/src/server/queries/issueQueries.tsfrontend/src/server/queries/moduleQueries.tsfrontend/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.tsfrontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsxfrontend/src/server/queries/issueQueries.tsfrontend/src/server/queries/moduleQueries.tsfrontend/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.tsfrontend/src/server/queries/moduleQueries.tsbackend/apps/mentorship/api/internal/queries/mentorship.pybackend/apps/mentorship/api/internal/mutations/module.pybackend/apps/mentorship/api/internal/nodes/module.pybackend/apps/mentorship/api/internal/nodes/mentee.pybackend/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.tsxfrontend/__tests__/unit/components/SingleModuleCard.test.tsxfrontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsxfrontend/src/app/my/mentorship/programs/[programKey]/modules/create/page.tsxfrontend/src/types/mentorship.tsfrontend/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.tsxfrontend/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.tsxfrontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsxfrontend/src/app/my/mentorship/programs/[programKey]/modules/create/page.tsxfrontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/edit/page.tsxfrontend/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.pybackend/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.pybackend/apps/mentorship/api/internal/mutations/module.pybackend/apps/mentorship/api/internal/nodes/module.pybackend/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) andunassigning(line 124) are verified in the codebase:
menteemodule_set: Django ORM reverse relation inbackend/apps/mentorship/api/internal/nodes/module.py:44unassigning: React state variable used across frontend components infrontend/src/hooks/useIssueMutations.tsand issue management pagesEntries 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
ExperienceLevelEnumvalues are single lowercase words ('beginner', 'intermediate', 'advanced', 'expert'), soupperFirstcorrectly 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
idfields to mock pull requests correctly aligns with the expandedPullRequesttype that now includesid,state, andmergedAtfields.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
idfields 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
handleEditandhandleCreate. 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_ISSUESquery 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:
- 50 issues is a reasonable maximum for the mentee profile page requirements
- Pagination should be added similar to
GET_MODULE_ISSUES(withoffsetparameter)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
idfield, maintaining consistency with the updatedPullRequesttype.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
levelfield 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 nullassigned_atat 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
usePathnamefromnext/navigationis the proper approach for obtaining the current pathname in Next.js 13+ app router, replacing the previous reliance onwindow.location. Based on learnings.Also applies to: 73-73, 77-77
89-93: LGTM! Clean integration of label display.The conditional rendering of
LabelListwithmaxVisible={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
idfield to the mock pull request aligns with the updatedPullRequesttype that now includesid,state, andmergedAtfields.frontend/src/app/my/mentorship/programs/[programKey]/modules/create/page.tsx (1)
42-42: LGTM! Consistent labels handling.The
labelsfield is properly initialized in the form state and parsed usingparseCommaSeparatedbefore mutation, following the same pattern asdomainsandtags. 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
labelsfield to bothUPDATE_MODULEandCREATE_MODULEmutation 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
PublishedModuleManagerthrough the package__init__.pyfollows standard Django patterns and enables clean usage of thepublished_modulesmanager 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 thePullRequesttype, 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 updatedModuletype that now includes alabels: 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.pyhassearch_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
summarytobodycorrectly matches GitHub's Issue API structure, where issues have abodyfield rather than asummaryfield.
521-528: LGTM: PR mock data extended to match type definitions.The addition of
id,state, andmergedAtfields to the mock pull request data aligns with the expandedPullRequestNodeGraphQL 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_issuestoautocomplete_fieldscorrectly 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
labelsfield is properly typed as a string and follows the established pattern for comma-separated input fields likedomainsandtags.
189-202: LGTM: Labels input field properly integrated.The new labels input field:
- Follows the same UI/UX pattern as the existing
domainsandtagsfields- Uses the existing
handleInputChangehandler 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-requeststarget 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-commandmechanismbackend/apps/mentorship/admin/__init__.py (2)
3-3: LGTM: IssueUserInterest admin import added.The import properly exposes the admin interface for the
IssueUserInterestmodel, which tracks user interest in issues within mentorship modules.
5-5: LGTM: MenteeModuleAdmin import added.The import properly exposes the admin interface for the
MenteeModulemodel, 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
CommentandLabelmodel exports extend the public API surface of thegithub.modelspackage, 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
stateandmerged_atfields to thePullRequestNodeproperly 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=Trueto make the relationship optional- Clear
verbose_name("Issues") for admin interface- Sensible
related_name("pull_requests") for reverse lookups from IssueThis 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
parseCommaSeparatedto 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
labelsandmenteesfields toDetailsCardPropsis 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_CHECKINGto conditionally importGithubfor 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_savefor 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
useParamsimproves type safety.
68-68: LGTM!The addition of
labels,mentees,programKey, andentityKeyprops 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: Therelated_issuesfield 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 viapr.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_issuesmanagement command implements label matching and populates theissuesfield viamodule.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.
backend/apps/mentorship/management/commands/mentorship_update_comments.py
Show resolved
Hide resolved
backend/apps/mentorship/migrations/0005_remove_task_level_module_issues_and_more.py
Show resolved
Hide resolved
...nd/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/[issueId]/page.tsx
Show resolved
Hide resolved
.../app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeHandle]/page.tsx
Outdated
Show resolved
Hide resolved
.../app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeHandle]/page.tsx
Show resolved
Hide resolved
|
There was a problem hiding this 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
Issueis 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
📒 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) andlabels(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: stringfield follows the same pattern asdomainsandtagsinModuleFormData, where form input is captured as a string and later transformed to an array in theModuletype.
84-125: LGTM! Comprehensive type definitions align with PR objectives.The new types (
CompletedLevel,Achievement,Penalty, andMenteeDetails) 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
MenteeDetailsare 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.




Proposed change
Resolves #2240
Task
MEDIA