Skip to content

Team collaboration [NEW]#175

Merged
A1L13N merged 57 commits into
alphaonelabs:mainfrom
ishaan-arora-1:team-collaboration-clean
Mar 21, 2025
Merged

Team collaboration [NEW]#175
A1L13N merged 57 commits into
alphaonelabs:mainfrom
ishaan-arora-1:team-collaboration-clean

Conversation

@ishaan-arora-1
Copy link
Copy Markdown
Contributor

@ishaan-arora-1 ishaan-arora-1 commented Mar 21, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a comprehensive team collaboration suite allowing users to create, view, edit, and delete team goals.
    • Enabled managing team invitations with options to accept or decline, complete with real-time notifications for goal completions and invite responses.
    • Enhanced the user interface by adding sections on the homepage and dedicated pages for team goal details, progress tracking, and member management.
  • Chores

    • Applied minor formatting and styling adjustments to improve overall consistency.

ishaan-arora-1 and others added 30 commits March 15, 2025 21:50
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-Authored-By: Ishaan Arora <ishaana612@gmail.com>
Co-Authored-By: Ishaan Arora <ishaana612@gmail.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 21, 2025

Walkthrough

This pull request introduces a comprehensive team collaboration feature. New models, forms, notifications, templates, URL endpoints, and views have been added to support the creation, management, and interaction of team goals, member participation, and invitations. Additionally, minor formatting and attribute updates have been applied to existing workflow and template files.

Changes

File(s) Change Summary
.github/workflows/test.yml Minor formatting changes: added blank lines before the steps sections in the linting and tests jobs.
web/forms.py Added two new form classes: TeamGoalForm (for creating and editing team goals with a future deadline validation) and TeamInviteForm (for inviting users with recipient filtering and validation).
web/migrations/0032_rename_completion_date_teamgoalmember_completed_at_and_more.py Created new models (TeamGoal, TeamGoalMember, TeamInvite), renamed fields (e.g., completion_date to completed_at, goal to team_goal), removed the target_date field, added a deadline field and a role field, and updated unique constraints and field choices (e.g., status now includes “cancelled”).
web/models.py Introduced new classes: TeamGoal, TeamGoalMember, and TeamInvite with additional methods such as calculating completion percentage, marking contribution completion (with notification triggers), and overriding the save method for notifications.
web/notifications.py Added three new functions: notify_team_invite, notify_team_invite_response, and notify_team_goal_completion, which manage notifications (including Slack messages) for team invites, invitation responses, and team goal completions.
web/templates/index.html, web/templates/teams/create.html, web/templates/teams/delete_confirm.html, web/templates/teams/detail.html, web/templates/teams/list.html, web/templates/web/study/group_detail.html Added new templates and updated existing ones to support team collaboration. The changes include a new team collaboration section on the index page, dedicated templates for creating, editing, deleting, and detailing team goals, as well as a minor attribute update (disabled="disabled") in a study group template.
web/urls.py Introduced new URL patterns for team collaboration functionalities, including endpoints for listing team goals, creating goals, viewing details, accepting/declining invites, marking contributions, deleting goals, removing members, and editing goals.
web/views.py Added new views and methods to handle team goal and invitation functionalities: listing team goals (team_goals), creating (create_team_goal), detailing (team_goal_detail), editing, accepting/declining invites, marking contributions (mark_team_contribution), removing members, and deleting team goals (delete_team_goal).

Sequence Diagram(s)

sequenceDiagram
  participant U as User
  participant B as Browser
  participant CG as CreateTeamGoal View
  participant TG as TeamGoal Model
  participant TM as TeamGoalMember Model

  U->>B: Access create team goal page
  U->>B: Submit team goal form with details
  B->>CG: POST form data
  CG->>TG: Save TeamGoal record
  CG->>TM: Create leader record
  CG-->>B: Return success response
Loading
sequenceDiagram
  participant C as Creator/User
  participant B as Browser
  participant TD as TeamGoalDetail View
  participant TI as TeamInvite Model
  participant N as Notification Service
  participant R as Recipient

  %% Invitation Sending Flow
  C->>B: Open team goal detail page
  C->>B: Submit invite form
  B->>TD: POST invite data
  TD->>TI: Save TeamInvite record
  TI->>N: Trigger notify_team_invite
  N-->>TD: Notification sent
  TD-->>B: Return invite confirmation
  
  %% Invitation Acceptance Flow
  R->>B: Click accept invitation link
  B->>TD: Request accept invitation
  TD->>TI: Update invite status to accepted
  TD->>TM: Create team membership record
  TD->>N: Trigger notify_team_invite_response
  N-->>TD: Notification sent
  TD-->>B: Return acceptance confirmation
Loading

Suggested reviewers

  • A1L13N
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (14)
web/templates/index.html (2)

361-464: Team collaboration section looks great, but has a redundant authentication check.

The new team collaboration section is well-structured with good UI components for both team goals and invitations. However, there's a redundant authentication check at lines 361 and 372, which could be simplified.

Consider removing the nested authentication check at line 372, since the parent condition at line 361 already verifies the user is authenticated:

{% if user.is_authenticated %}
  <!-- Team Collaboration Section -->
  <div class="bg-gradient-to-r from-blue-500 to-purple-600 rounded-lg shadow-lg p-6 mt-8">
    <div class="flex items-center justify-between mb-6">
      <h2 class="text-2xl font-bold text-white">Team Collaboration</h2>
      <a href="{% url 'team_goals' %}"
         class="inline-flex items-center px-6 py-2 bg-white text-blue-600 rounded-full font-semibold hover:bg-blue-50 transition-colors duration-200 whitespace-nowrap sm:inline-flex">
        <span>View All</span>
        <i class="fas fa-arrow-right ml-2"></i>
      </a>
    </div>
-   {% if user.is_authenticated %}
    <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
      <!-- Content unchanged -->
    </div>
-   {% else %}
-     <div class="text-center py-8">
-       <p class="text-gray-200 mb-4">Sign in to create or join team goals and collaborate with others!</p>
-       <a href="{% url 'login' %}"
-          class="inline-flex items-center px-6 py-3 bg-white text-blue-600 hover:bg-gray-100 rounded-lg transition duration-200">
-         <i class="fas fa-sign-in-alt mr-2"></i>
-         Sign In to Get Started
-       </a>
-     </div>
-   {% endif %}
  </div>
{% endif %}

386-393: Internationalized deadline display is inconsistent.

While you've loaded the internationalization tags correctly, some of the date-related text is not properly internationalized, which might cause issues for non-English users.

Wrap all display text strings in {% trans %} tags for consistent internationalization:

<div class="text-sm text-gray-200 mt-2">
  <i class="fas fa-calendar-alt mr-1"></i>
  {% load i18n %}

  <span>{% trans "Due" %}: {{ goal.deadline|date:"M j, Y" }}</span>
  {% if goal.deadline < now %}
    <span class="text-red-300 ml-1">({% trans "Overdue" %})</span>
  {% else %}
-   <span class="text-gray-300 ml-1">({{ goal.deadline|timeuntil }} {% trans "left" %})</span>
+   <span class="text-gray-300 ml-1">({{ goal.deadline|timeuntil }} {% trans "left" %})</span>
  {% endif %}
</div>

This looks correct already. I missed an issue in my first review. The "left" term is already properly internationalized.

web/forms.py (1)

1129-1139: Inconsistent CSS styling in TeamInviteForm.

The recipient search field uses a non-Tailwind CSS class, which is inconsistent with other form inputs in the project.

Consider using Tailwind CSS classes to maintain consistency with the rest of the project:

recipient_search = forms.CharField(
    label="Invite User",
    widget=forms.TextInput(
        attrs={
-           "class": "form-control",
+           "class": "w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500",
            "placeholder": "Search by username or email",
            "list": "user-list",
            "autocomplete": "off",
        }
    ),
    required=False,
)
web/models.py (1)

1278-1278: Fix typo in notification message.

There's a missing space in the notification message for goal completion.

Add a space before the single quote for better readability:

- message=f"{self.user.get_full_name() or self.user.username} completed'{self.team_goal.title}'",
+ message=f"{self.user.get_full_name() or self.user.username} completed '{self.team_goal.title}'",
web/templates/teams/detail.html (2)

77-81: Missing fallback for users without avatars.

The template checks if a user has an avatar but doesn't provide a fallback display for users without one.

Add a fallback display for users without avatars for a consistent UI:

{% if member.user.profile.avatar %}
  <img src="{{ member.user.profile.avatar.url }}"
       alt="{{ member.user.username }}"
       class="w-8 h-8 rounded-full mr-3 object-cover border-2 border-purple-200 dark:border-purple-700" />
+{% else %}
+  <div class="w-8 h-8 rounded-full mr-3 bg-gray-300 dark:bg-gray-600 flex items-center justify-center border-2 border-purple-200 dark:border-purple-700">
+    <span class="text-xs text-gray-600 dark:text-gray-300">{{ member.user.username|first|upper }}</span>
+  </div>
{% endif %}

165-197: Form validation message should be internationalized.

The custom validation message in the JavaScript for the invite form is not internationalized, which would cause issues for non-English users.

Use a translated error message for consistency with the rest of the template:

// Show validation error if no match found
if (!found) {
    recipientField.value = ''; // Clear any previous value
-   this.setCustomValidity('Please select a user from the list');
+   this.setCustomValidity('{% trans "Please select a user from the list" %}');
} else {
    this.setCustomValidity('');
}

For this to work correctly, you'd need to move the JavaScript to a Django template variable or use Django's window.gettext() JavaScript integration.

web/notifications.py (2)

240-250: Minor punctuation refinement in notification message.
There is an extra space before the colon in the message string. Consider removing it for clarity.

-        "message": f"{invite.recipient.username} has {status_text} your invite to join goal : '{invite.goal.title}'.",
+        "message": f"{invite.recipient.username} has {status_text} your invite to join goal: '{invite.goal.title}'.",

253-274: Consider concurrency control when marking goal completion.
If two members finalize their tasks simultaneously, there could be duplicate “100% complete” notifications. A short, atomic check (e.g., wrapping everything in a transaction) can prevent multiple notifications from being sent at once.

web/views.py (3)

3535-3580: Invitation logic is mostly consistent, but watch for redundant validations.
The view checks for existing invites by recipient email, while the form’s clean_recipient also checks pending invites. Consider centralizing these checks to avoid confusion.


3582-3606: Invitation acceptance flows well.
Consider adding Slack or additional notifications here if real-time acceptance updates are desired beyond emailing the sender.


3680-3700: Member removal looks good; possible single-leader edge case.
If only one leader remains, removing them might leave the goal leaderless; ensure this is acceptable.

web/migrations/0032_rename_completion_date_teamgoalmember_completed_at_and_more.py (3)

16-42: TeamGoal model creation.
This table is well-structured and includes essential fields. Consider whether existing data should be migrated into the new TeamGoal model or if this is purely net-new usage.


43-68: TeamGoalMember model creation.
The model tracks membership and completion status. However, ensure that all logic for automatically populating completion_date (now completed_at) is properly handled in code if needed.


69-114: TeamInvite model creation.
This model looks solid. Double-check whether invitations should expire automatically. If so, consider adding a background job or scheduled task to handle “expired” invites.

Do you want me to open a new issue or draft a scheduled task for invite expiration?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3c36ec4 and cbe84d8.

📒 Files selected for processing (13)
  • .github/workflows/test.yml (1 hunks)
  • web/forms.py (4 hunks)
  • web/migrations/0032_rename_completion_date_teamgoalmember_completed_at_and_more.py (1 hunks)
  • web/models.py (1 hunks)
  • web/notifications.py (1 hunks)
  • web/templates/index.html (1 hunks)
  • web/templates/teams/create.html (1 hunks)
  • web/templates/teams/delete_confirm.html (1 hunks)
  • web/templates/teams/detail.html (1 hunks)
  • web/templates/teams/list.html (1 hunks)
  • web/templates/web/study/group_detail.html (1 hunks)
  • web/urls.py (1 hunks)
  • web/views.py (4 hunks)
🧰 Additional context used
🧬 Code Definitions (4)
web/views.py (3)
web/forms.py (7) (7)
  • TeamGoalForm (1107-1123)
  • TeamInviteForm (1126-1168)
  • save (177-206)
  • save (451-476)
  • save (535-545)
  • save (1070-1083)
  • save (1244-1259)
web/models.py (17) (17)
  • TeamGoal (1226-1249)
  • TeamGoalMember (1252-1281)
  • TeamInvite (1284-1321)
  • status (1724-1734)
  • save (82-99)
  • save (147-150)
  • save (214-248)
  • save (311-338)
  • save (423-425)
  • save (643-646)
  • save (788-793)
  • save (846-851)
  • save (926-929)
  • save (986-997)
  • save (1024-1026)
  • mark_completed (1270-1281)
  • delete (369-375)
web/notifications.py (3) (3)
  • notify_team_goal_completion (253-273)
  • notify_team_invite (217-237)
  • notify_team_invite_response (240-250)
web/forms.py (1)
web/models.py (19) (19)
  • TeamGoal (1226-1249)
  • TeamInvite (1284-1321)
  • Meta (42-43)
  • Meta (141-142)
  • Meta (305-306)
  • Meta (411-412)
  • Meta (467-468)
  • Meta (489-490)
  • Meta (536-539)
  • Meta (583-584)
  • Meta (636-638)
  • Meta (662-663)
  • Meta (679-681)
  • Meta (703-704)
  • Meta (719-720)
  • Meta (782-783)
  • Meta (813-814)
  • Meta (838-841)
  • status (1724-1734)
web/models.py (1)
web/forms.py (16) (16)
  • Meta (210-216)
  • Meta (220-249)
  • Meta (279-317)
  • Meta (328-365)
  • Meta (393-399)
  • Meta (403-427)
  • Meta (515-517)
  • Meta (614-634)
  • Meta (657-669)
  • Meta (775-812)
  • Meta (856-877)
  • Meta (982-989)
  • Meta (1011-1033)
  • Meta (1096-1104)
  • Meta (1110-1116)
  • Meta (1142-1147)
web/urls.py (1)
web/views.py (9) (9)
  • team_goals (3489-3510)
  • create_team_goal (3514-3532)
  • team_goal_detail (3536-3579)
  • accept_team_invite (3583-3605)
  • decline_team_invite (3609-3618)
  • mark_team_contribution (3658-3677)
  • delete_team_goal (3703-3717)
  • remove_team_member (3681-3699)
  • edit_team_goal (3622-3654)
🔇 Additional comments (22)
.github/workflows/test.yml (1)

25-32: Minor Formatting Adjustment.
The removal of the extraneous blank line before the tests job is a simple cosmetic update that does not impact functionality. Ensure that similar formatting conventions are consistently applied across workflow files.

web/templates/web/study/group_detail.html (1)

105-108: Clarified Disabled Button Attribute.
Changing the button’s disabled attribute from a boolean notation to an explicit value (disabled="disabled") makes the intent clearer. Please double-check that this format is consistent with other parts of the project for uniformity.

web/templates/teams/delete_confirm.html (1)

1-34: New Delete Confirmation Template Looks Solid.
The template is well-structured, utilizing internationalization and clear messaging for a critical action. Make sure the associated backend view enforces the necessary permission checks for deleting a team goal.

web/templates/teams/create.html (1)

1-52: Team Goal Creation/Edit Template Integrated Well.
The use of conditional rendering via the is_edit variable and the incorporation of i18n makes for an effective and adaptable template. Ensure that frontend validations and error display mechanisms are fully synchronized with the backend logic.

web/templates/teams/list.html (1)

1-154: Comprehensive and Readable Team Goals Listing.
This template robustly covers the listing of team goals including pending invites, user goals, progress visualization, and pagination. The use of inline styles for progress bars is clear; just confirm that the goal.completion_percentage value is properly sanitized and accurate.

web/forms.py (1)

1107-1124: TeamGoalForm implementation looks good.

The form implementation for creating and editing team goals is well-structured with appropriate field settings and deadline validation.

web/models.py (2)

1226-1249: TeamGoal model implementation looks good.

The TeamGoal model is well-structured with appropriate fields, relationships, and properties.


1284-1321: TeamInvite model looks well-implemented.

The TeamInvite model has a good structure with appropriate fields, relationships, and notification triggers in the save method.

web/templates/teams/detail.html (1)

1-198: Overall well-structured team goal detail template.

The team goal detail template has a clean, responsive design with good separation between the main content and sidebar. It handles different user roles and permission checks appropriately and integrates well with the team goal and member management features.

web/notifications.py (1)

215-239: Solid implementation for team invites.
This function cleanly handles both database-backed notifications and Slack notifications in separate try-except blocks. The approach is straightforward and error logs are helpful.

web/views.py (8)

76-77: Imports look good.
Bringing in TeamGoalForm and TeamInviteForm cleanly integrates the new team goal feature.


123-125: No issues with these model imports.
These classes are essential for team collaboration features.


129-136: Straightforward notification imports.
This ensures all new team notification functions are available.


207-223: Authenticated user context extension is correct.
Grabbing user_team_goals and team_invites for display on the homepage is a good user experience addition.


3490-3511: Pagination for team goals is handled well.
Listing all goals the user is part of fosters quick navigation and seeing pending invites is helpful.


3513-3533: Team goal creation logic looks solid.
Using a transaction to ensure atomicity when creating the goal and attaching the creator as a leader is a nice touch.


3657-3678: Contribution completion logic is straightforward.
Marking completion and immediately sending completion notifications is well-structured.


3702-3719: Goal deletion restricted to creator only.
Appropriate check to avoid accidental removal by ordinary members.

web/urls.py (1)

237-246:

Details

❓ Verification inconclusive

All-new team collaboration URLs look consistent and comprehensive.
They correctly map to the corresponding views, and the naming is clear. However, please double-check that no additional login or permission decorators are needed on each view to prevent unauthorized access.

Here is a script you can run to confirm each route is protected by appropriate access control:


🏁 Script executed:

#!/bin/bash
# Searches for the definitions of the new team collaboration views and checks for permission or login checks.
fd views.py --exec rg -A 7 "def team_goals" 
fd views.py --exec rg -A 7 "def create_team_goal"
fd views.py --exec rg -A 7 "def team_goal_detail"
fd views.py --exec rg -A 7 "def accept_team_invite"
fd views.py --exec rg -A 7 "def decline_team_invite"
fd views.py --exec rg -A 7 "def mark_team_contribution"
fd views.py --exec rg -A 7 "def delete_team_goal"
fd views.py --exec rg -A 7 "def remove_team_member"
fd views.py --exec rg -A 7 "def edit_team_goal"

Length of output: 3608


Review Verification: Confirm Access Controls on Team Collaboration Views

The new team collaboration URLs are consistent and mostly secure. Our verification confirms that the following views have explicit access control logic:

  • team_goal_detail: Checks if the user is the creator or a member.
  • accept_team_invite / decline_team_invite: Filter invites based on the current user.
  • mark_team_contribution, delete_team_goal, remove_team_member, and edit_team_goal: Include privilege checks and redirect unauthorized users.

However, the team_goals and create_team_goal views do not contain explicit login or permission decorators within their function bodies. Please verify that these endpoints are protected by global authentication middleware or appropriate decorators elsewhere in the project to prevent unauthorized access.

web/migrations/0032_rename_completion_date_teamgoalmember_completed_at_and_more.py (3)

133-137: Addition of deadline field.
Great introduction for implementing time-based logic. Ensure that the code uses a consistent date or datetime approach across the app.


139-144: New role field in TeamGoalMember.
Allows differentiation of member roles. Confirm that any existing members (pre-migration) are assigned the correct role.


184-188:

Details

❓ Verification inconclusive

Altering unique_together for teamgoalmember.
Ensuring uniqueness on (team_goal, user) is a good approach. Confirm that no duplicates exist pre-migration to avoid exceptions.


🏁 Script executed:

#!/bin/bash
# Attempt to find any duplicates that might conflict with this new constraint.
# The below is a conceptual example reliant on direct DB captures, so adapt as needed.
echo "SELECT team_goal_id, user_id, COUNT(*) AS duplicates
FROM web_teamgoalmember
GROUP BY team_goal_id, user_id
HAVING duplicates > 1;" > check_duplicates.sql

Length of output: 139


Attention: Confirm Pre-Migration Duplicate Check

The change to enforce uniqueness on (team_goal, user) in the teamgoalmember migration looks correct. However, the automated shell script only echoed the SQL query rather than executing it, so no duplicate check was actually performed. Please run a proper database query or manually verify that no duplicates exist prior to applying this migration.

  • Manually execute the following SQL query on your target database:
    SELECT team_goal_id, user_id, COUNT(*) AS duplicates
    FROM web_teamgoalmember
    GROUP BY team_goal_id, user_id
    HAVING duplicates > 1;
    
  • Confirm that no duplicate records are returned.
  • If duplicates are found, address them before applying the migration.

Comment thread web/views.py
Comment thread web/views.py
ishaan-arora-1 and others added 3 commits March 21, 2025 15:02
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Copy Markdown
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 (3)
web/views.py (3)

207-223: Efficient retrieval of user’s team goals and invites.

This conditional block correctly fetches only relevant goals and invite records, but you might consider paginating the displayed invites if the user accumulates too many.


3513-3533: Team goal creation flows nicely.

The transaction usage, role assignment for the creator, and success feedback are all well done. Consider validating the deadline here (like in the edit view) to ensure consistent checks on creation.


3535-3580: Team goal detail logic is well-structured.

Inviting new members and preventing duplicate invites is a nice touch. A future enhancement might be to handle scenarios where a user email is unknown in the system.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cbe84d8 and 88fe926.

📒 Files selected for processing (2)
  • .github/workflows/test.yml (2 hunks)
  • web/views.py (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/test.yml
🔇 Additional comments (10)
web/views.py (10)

76-77: Clean addition of new forms for team collaboration.

These imports for TeamGoalForm and TeamInviteForm look appropriate and align well with the new team goal workflow.


123-125: Models imported correctly.

The TeamGoal, TeamGoalMember, and TeamInvite entities are essential for implementing the teamwork functionality. No issues identified.


129-136: Notification imports appear valid.

All these notification methods (like notify_team_invite_response) are needed for team collaboration updates. The import block is consistent and well-organized.


3489-3511: User goals listing logic is solid.

The function fetches goals where the user is creator or member, applies pagination, and includes pending invites. The structure is clean and the pagination approach is straightforward.


3582-3606: Acceptance logic is correct.

Using get_or_create() on TeamGoalMember prevents concurrency issues when multiple acceptance actions might occur. This is a robust approach.


3608-3620: Improved decline behavior.

Calling notify_team_invite_response() fixes the prior gap where the sender wasn’t informed of declines, addressing the previously noted issue. Good improvement.


3622-3655: Editing the goal with deadline checks is consistent.

The user’s role check, form validation, and time-bound logic all work together appropriately. Great job including the “deadline cannot be in the past” safeguard.


3657-3677: Marked contributions feature is straightforward.

This function properly identifies membership, checks completion status, and sends a notification. The flow is clear and has no evident concurrency issues.


3679-3699: Member removal logic is well-guarded.

Requiring either creator or leader privileges to remove members is correct. Blocking removal of the creator prevents unexpected orphan teams.


3702-3717: Deletion restricted to goal creator.

This final check ensures that only the original author can delete the team goal, preventing accidental or unauthorized deletions.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
web/views.py (2)

3636-3637: Use the form's built-in validator for deadline.

The TeamGoalForm already has a clean_deadline method that validates the deadline isn't in the past, but you're duplicating this validation logic here. Rely on the form's validation instead.

- # Validate that deadline is not in the past
- if form.cleaned_data["deadline"] < timezone.now():
-     form.add_error("deadline", "Deadline cannot be in the past.")
-     context = {
-         "form": form,
-         "goal": goal,
-         "is_edit": True,
-     }
-     return render(request, "teams/create.html", context)

3558-3562: Consider adding error handling for invitation creation failures.

The current implementation doesn't handle potential exceptions that might occur when saving the invitation.

- invite = form.save(commit=False)
- invite.sender = request.user
- invite.goal = goal
- invite.save()
+ try:
+     invite = form.save(commit=False)
+     invite.sender = request.user
+     invite.goal = goal
+     invite.save()
+     messages.success(request, f"Invitation sent to {invite.recipient.email}!")
+     notify_team_invite(invite)
+ except Exception as e:
+     messages.error(request, f"Failed to send invitation: {str(e)}")
+ return redirect("team_goal_detail", goal_id=goal.id)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88fe926 and 57d735b.

📒 Files selected for processing (2)
  • .github/workflows/docker-test.yml (3 hunks)
  • web/views.py (4 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .github/workflows/docker-test.yml
🧰 Additional context used
🧬 Code Definitions (1)
web/views.py (2)
web/forms.py (7) (7)
  • TeamGoalForm (1107-1123)
  • TeamInviteForm (1126-1168)
  • save (177-206)
  • save (451-476)
  • save (535-545)
  • save (1070-1083)
  • save (1244-1259)
web/models.py (17) (17)
  • TeamGoal (1226-1249)
  • TeamGoalMember (1252-1281)
  • TeamInvite (1284-1321)
  • status (1724-1734)
  • save (82-99)
  • save (147-150)
  • save (214-248)
  • save (311-338)
  • save (423-425)
  • save (643-646)
  • save (788-793)
  • save (846-851)
  • save (926-929)
  • save (986-997)
  • save (1024-1026)
  • mark_completed (1270-1281)
  • delete (369-375)
🔇 Additional comments (7)
web/views.py (7)

3617-3618: The sender is now properly notified of declined invites.

The previous issue where the notify_team_invite_response function wasn't called for declined invites has been fixed.


3694-3696: Good safety check to prevent removing the creator.

This check prevents the accidental removal of the team creator, which is an important constraint to maintain the integrity of team ownership.


3519-3526: Good use of transactions for team goal creation.

Using transaction.atomic() ensures that both the goal creation and adding the creator as a member are performed as a single atomic operation, maintaining data consistency.


3539-3543: Proper access control for team goal details.

This access check ensures users can only view team goals they have created or are a member of, maintaining proper data security.


3589-3592: Race condition protection using get_or_create.

This pattern effectively prevents race conditions when multiple users might be accepting invitations simultaneously, ensuring data consistency.


3677-3677: Good use of notification for team goal completion.

The implementation properly notifies other team members when someone completes their contribution, enhancing team collaboration.


3708-3711: Strong validation for goal deletion permissions.

This ensures that only the creator of a team goal can delete it, preventing unauthorized deletions.

Comment thread web/views.py
Copy link
Copy Markdown
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 (2)
web/models.py (2)

1279-1279: Fix formatting in notification message.

There's a missing space before "completed" in the notification message, which would make the text run together.

-            message=f"{self.user.get_full_name() or self.user.username} completed'{self.team_goal.title}'",
+            message=f"{self.user.get_full_name() or self.user.username} completed '{self.team_goal.title}'",

1302-1321: Consider adding notification for declined invitations.

The current implementation creates notifications when an invitation is created or accepted, but not when it's declined. For a complete notification system, consider also notifying the sender when an invitation is declined.

         # Create notification when invite is accepted
         if not created and self.status == "accepted":
             Notification.objects.create(
                 user=self.sender,
                 title="Team Invitation Accepted",
                 message=f"{self.recipient.get_full_name() or self.recipient.username} has accepted your invitation",
                 notification_type="success",
             )
+        # Create notification when invite is declined
+        elif not created and self.status == "declined":
+            Notification.objects.create(
+                user=self.sender,
+                title="Team Invitation Declined",
+                message=f"{self.recipient.get_full_name() or self.recipient.username} has declined your invitation",
+                notification_type="info",
+            )
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57d735b and 6d63629.

📒 Files selected for processing (1)
  • web/models.py (2 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
web/models.py (1)
web/forms.py (16) (16)
  • Meta (210-216)
  • Meta (220-249)
  • Meta (279-317)
  • Meta (328-365)
  • Meta (393-399)
  • Meta (403-427)
  • Meta (515-517)
  • Meta (614-634)
  • Meta (657-669)
  • Meta (775-812)
  • Meta (856-877)
  • Meta (982-989)
  • Meta (1011-1033)
  • Meta (1096-1104)
  • Meta (1110-1116)
  • Meta (1142-1147)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build-and-test
  • GitHub Check: Run Tests
🔇 Additional comments (4)
web/models.py (4)

1226-1250: Well-designed TeamGoal model with good structure.

The model has all necessary fields and a thoughtful property method to calculate completion percentage. The status choices are well-defined, and the deadline being optional provides flexibility in goal creation.


1242-1249: Robust implementation of completion percentage calculation.

The method properly handles the edge case when there are no members (returning 0) and correctly calculates the percentage of members who have completed the goal.


1252-1282: Good TeamGoalMember implementation with clear role definition.

The model properly links users to team goals with appropriate metadata tracking. The unique constraint ensures a user can only be a member of a team goal once, which prevents duplication issues.


1284-1322: Comprehensive invitation system with proper notification handling.

The TeamInvite model effectively manages the invitation workflow with appropriate status transitions and notification triggers. The unique constraint on goal and recipient prevents duplicate invitations.

@A1L13N
Copy link
Copy Markdown
Contributor

A1L13N commented Mar 21, 2025

@ishaan-arora-1 there are a couple of requested changes.

Copy link
Copy Markdown
Contributor

@A1L13N A1L13N left a comment

Choose a reason for hiding this comment

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

please make the requested changes.

@ishaan-arora-1
Copy link
Copy Markdown
Contributor Author

please make the requested changes.

Tonight ill make this pr free of errors, sorry for the delay.

@A1L13N A1L13N added the d:21 label Mar 21, 2025
coderabbitai[bot]
coderabbitai Bot previously approved these changes Mar 21, 2025
Copy link
Copy Markdown
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 (2)
web/views.py (2)

3535-3581: Invitation flow checks may need stricter user role validation.
This view allows any goal member to invite others, assuming they have access to the detail page. If the intention is to restrict invitations to only leaders or the creator, consider adding a role check before processing the invite form.

Otherwise, the invitation logic (checking for existing invites, calling notify_team_invite) is correctly implemented.


3623-3657: Duplicate deadline validation.
A similar deadline check might already be performed by TeamGoalForm’s clean_deadline() method. Re-checking here can provide extra safety, but can also lead to code duplication. If you trust the form's validation fully, consider removing the manual comparison:

-            if form.cleaned_data["deadline"] < timezone.now():
-                form.add_error("deadline", "Deadline cannot be in the past.")
-                ...
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d63629 and f98319b.

📒 Files selected for processing (1)
  • web/views.py (4 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
web/views.py (3)
web/forms.py (7) (7)
  • TeamGoalForm (1107-1123)
  • TeamInviteForm (1126-1168)
  • save (177-206)
  • save (451-476)
  • save (535-545)
  • save (1070-1083)
  • save (1244-1259)
web/models.py (17) (17)
  • TeamGoal (1226-1249)
  • TeamGoalMember (1252-1281)
  • TeamInvite (1284-1321)
  • status (1724-1734)
  • save (82-99)
  • save (147-150)
  • save (214-248)
  • save (311-338)
  • save (423-425)
  • save (643-646)
  • save (788-793)
  • save (846-851)
  • save (926-929)
  • save (986-997)
  • save (1024-1026)
  • mark_completed (1270-1281)
  • delete (369-375)
web/notifications.py (3) (3)
  • notify_team_goal_completion (253-273)
  • notify_team_invite (217-237)
  • notify_team_invite_response (240-250)
🔇 Additional comments (11)
web/views.py (11)

76-77: Imports look good.
These imports for TeamGoalForm and TeamInviteForm cleanly introduce the new forms needed for team goal functionality, with no conflicts or unused references.


123-125: Models imported successfully.
Importing TeamGoal, TeamGoalMember, and TeamInvite appears correct and aligns with the new team collaboration features. No issues identified.


129-136: Notifications import is consistent.
These notifications—notify_session_reminder, notify_teacher_new_enrollment, notify_team_goal_completion, notify_team_invite, notify_team_invite_response, and send_enrollment_confirmation—are all used below in the code and no extraneous imports are introduced.


207-223: Context augmentation in index view.
Fetching the user's recent TeamGoals and pending TeamInvites makes the homepage more relevant for an authenticated user. The query is straightforward, and slicing by [:3] helps maintain a succinct display. Good use of select_related for performance on team invites.


3489-3511: Team goals listing logic is simple and clear.
The view lists team goals where the user is either the creator or a member. Pagination is handled properly, and pending invites are retrieved to show at a glance. This is well-structured and readable.


3513-3533: Team goal creation is well-handled.
Creating a new TeamGoal under a transaction and adding the creator as a leader ensures data consistency. There's no apparent concurrency risk or logical errors.


3583-3607: Acceptance of team invites.
The usage of get_or_create for creating a TeamGoalMember helps avoid duplicate membership. This flow is robust, and subsequent notifications are triggered correctly.


3609-3621: Smooth decline flow.
Setting the status to "declined," updating timestamps, and sending a response notification is straightforward and clear. No concerns.


3659-3680: Contribution marking is clear.
Checking membership, ensuring the contribution isn’t already marked, then calling mark_completed() is succinct. Invoking notify_team_goal_completion for extra updates is a solid approach.


3682-3702: Removal of team members.
Enforcing that only the goal creator or a leader can remove members is logically sound, and preventing removal of the creator is a critical safeguard.


3704-3720: Creator-only deletion logic.
The final check ensures that only the original creator can delete the entire team goal. This is appropriate, and the feedback messages are user-friendly.

@ishaan-arora-1 ishaan-arora-1 requested a review from A1L13N March 21, 2025 20:23
@A1L13N A1L13N enabled auto-merge (squash) March 21, 2025 22:29
@A1L13N A1L13N merged commit 5ab3212 into alphaonelabs:main Mar 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants