-
-
Notifications
You must be signed in to change notification settings - Fork 323
Feature/team badges #5368
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: main
Are you sure you want to change the base?
Feature/team badges #5368
Conversation
|
👋 Hi @karunarapolu! This pull request needs a peer review before it can be merged. Please request a review from a team member who is not:
Once a valid peer review is submitted, this check will pass automatically. Thank you! |
WalkthroughAdds team-scoped badges: new TeamBadge model and Badge.scope, migrations, admin and fixtures; automatic evaluation via signals and helper functions; views, URLs and templates for team badges and assignment; tests, forms, and UI updates; several non-functional formatting/comment tweaks across codebase. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant TeamsView as Teams View (assign_team_member_badge)
participant DB as Database (TeamBadge)
participant Redirect as Response/Redirect
Client->>TeamsView: POST assign badge (admin)
TeamsView->>DB: check team membership & existing assignment
alt valid & not exists
TeamsView->>DB: create TeamBadge record
TeamsView->>Redirect: redirect with success message
else invalid / not authorized
TeamsView->>Redirect: redirect with error message
end
sequenceDiagram
participant System
participant Signals as Signal Handler
participant Evaluator as evaluate_team_badges
participant DB as Database (TeamBadge/Badge)
participant Notification as Optional downstream actions
System->>Signals: Contribution or Issue post_save
Signals->>Evaluator: evaluate team badges for team
Evaluator->>DB: query metrics, contributors, existing TeamBadge
alt criteria met & not awarded
Evaluator->>DB: create TeamBadge (award)
Evaluator->>Notification: emit side-effects (optional)
else criteria not met & badge exists
Evaluator->>DB: remove TeamBadge (revoke)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro Knowledge base: Disabled due to 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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). (2)
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 |
📊 Monthly LeaderboardHi @karunarapolu! Here's how you rank for December 2025:
Leaderboard based on contributions in December 2025. Keep up the great work! 🚀 |
❌ Pre-commit checks failedThe pre-commit hooks found issues that need to be fixed. Please run the following commands locally to fix them: # Install pre-commit if you haven't already
pip install pre-commit
# Run pre-commit on all files
pre-commit run --all-files
# Or run pre-commit on staged files only
pre-commit runAfter running these commands, the pre-commit hooks will automatically fix most issues. 💡 Tip: You can set up pre-commit to run automatically on every commit by running: pre-commit installPre-commit outputFor more information, see the pre-commit documentation. |
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: 12
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
website/feed_signals.py (1)
8-26: Import error:Countshould be fromdjango.db.models, not.models.The
Countaggregate function is imported from.models(the local models module), but it should be imported fromdjango.db.models. This will cause anImportErrorat runtime.🔎 Proposed fix
+from django.db.models import Count + from .models import ( Activity, BaconEarning, Badge, Bid, - Count, Contribution, ForumPost,
🧹 Nitpick comments (14)
.env.example (1)
36-36: Remove the extra blank line to maintain consistent section spacing.The insertion of a blank line at line 36 creates two consecutive blank lines between the Slack and BlueSky sections, which is inconsistent with the single-line spacing used elsewhere in the file (e.g., between SUPERUSER, DATABASE, SENTRY, and SLACK sections).
🔎 Proposed fix
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL - #BlueSky User Details BLUESKY_USERNAME=example.bsky.socialwebsite/forms.py (1)
10-22: Remove unused imports.
BadgeandTeamBadgeare imported but not used anywhere in this file. These unused imports should be removed to keep the codebase clean.🔎 Proposed fix
from website.models import ( Bid, - Badge, Hackathon, HackathonPrize, HackathonSponsor, IpReport, Job, Monitor, Organization, ReminderSettings, Repo, Room, UserProfile, - TeamBadge, )website/management/commands/update_github_issues.py (1)
165-176: Semantics preserved forclosed_at/merged_at; optional micro‑refactorThe new ternary expressions keep the original behavior (nullable
closed_at,merged_atonly when merged). If you want to reduce duplication, you could reuse the previously parsedmerged_atinstead of reparsing from the JSON.Optional small cleanup using existing
merged_at- github_issue, created = GitHubIssue.objects.update_or_create( + github_issue, created = GitHubIssue.objects.update_or_create( @@ - "closed_at": ( - timezone.make_aware(datetime.strptime(pr["closed_at"], "%Y-%m-%dT%H:%M:%SZ")) - if pr.get("closed_at") - else None - ), - "merged_at": ( - timezone.make_aware( - datetime.strptime(pr["pull_request"]["merged_at"], "%Y-%m-%dT%H:%M:%SZ") - ) - if merged - else None - ), + "closed_at": ( + timezone.make_aware(datetime.strptime(pr["closed_at"], "%Y-%m-%dT%H:%M:%SZ")) + if pr.get("closed_at") + else None + ), + # Reuse the earlier parsed merged_at value + "merged_at": merged_at if merged else None,website/templates/includes/sidenav.html (1)
319-325: User & team badge links in sidenav wired correctly; label tweak optionalThe new
user_badgesentry under Users andteam_badgesentry under Teams both use the same active-state pattern as neighboring links and look functionally sound.If you want to make the distinction even clearer in the UI, you could consider renaming the team submenu label to something like “Team Badges” while keeping the URL the same, but that’s purely cosmetic.
Also applies to: 370-376
website/templates/profile.html (2)
519-522: Team label rendering is fine; optional UX polishShowing
user_badge.teamin red above the awarded date works, but you might consider prefixing it with a short label (e.g., “Team:”) or using a slightly smaller font so it visually reads as metadata rather than a second title. Not required, just a UX refinement.
953-1552: Large legacy commented-out profile layoutYou updated the URL here to
user_badges, which keeps even the legacy block consistent. Given this entire section is wrapped in{% comment %}, consider deleting it in a follow-up to reduce noise and avoid future inconsistencies between live and commented code.website/views/core.py (1)
1457-1471: Scope-aware badge_list behavior is correct; consider minor refinementsThe branching on
scope == "team"withscope__in=["team", "topuser_team"]vs user-scoped badges annotated byuser_countmatches the new Badge.scope semantics and URL wiring.Two small, non-blocking suggestions:
- Pass
scopeinto the context sobadges.htmlcan easily adjust headings/layout based on whether it’s showing user or team badges.- Add a deterministic ordering to the team branch (e.g.,
.order_by("title")or"-created_at") to avoid implicit DB ordering differences across backends.Otherwise this looks good.
website/tests/test_team_badges.py (1)
40-45: Unique-constraint test is too generic and may not reflect the model
test_team_badge_unique_constraintasserts that anyExceptionis raised on a duplicate(team, badge)TeamBadge, but:
- The current
TeamBadgemodel snippet does not show a uniqueness constraint; without one, this test will fail because the second create will succeed.- Even if you add a constraint, catching a broad
Exceptioncan allow unrelated bugs (e.g., DB connectivity issues) to make the test pass.Consider either:
- Adding an explicit
UniqueConstraint/unique_togetheron the intended fields and asserting a specific exception (typicallyIntegrityError), or- Removing this test if you intentionally allow multiple
TeamBadgerows for the same(team, badge)combination.website/views/teams.py (1)
4-6: Unused import:defaultdict.The
defaultdictimport is not used anywhere in this file.🔎 Proposed fix
-from collections import defaultdict - -website/migrations/0263_alter_badge_scope.py (1)
1-22: LGTM!This migration correctly updates the
scopefield choices to use a human-readable label "Topuser Team" instead of the raw value "topuser_team". The dependency chain is correct.Consider squashing migrations 0261, 0262, and 0263 before merging to production to reduce migration overhead, but this is optional.
website/models.py (1)
1697-1712: Consider adding a unique constraint to prevent duplicate badge awards.The
TeamBadgemodel correctly associates badges with teams and optionally with users. However, without a database-level constraint, duplicate badges could be awarded if the application-level check inaward_team_badgeis bypassed or encounters a race condition.Also, adding
related_nameto ForeignKey fields would improve reverse query clarity.🔎 Proposed improvements
class TeamBadge(models.Model): - team = models.ForeignKey(Organization, on_delete=models.CASCADE) - user=models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, default=None)# assign a indivitual user the badge for achivement in a group - badge = models.ForeignKey(Badge, on_delete=models.CASCADE) + team = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name="team_badges") + user = models.ForeignKey( + User, on_delete=models.CASCADE, null=True, blank=True, default=None, + related_name="team_badge_awards", + help_text="Assign badge to individual user for achievement in a team" + ) + badge = models.ForeignKey(Badge, on_delete=models.CASCADE, related_name="team_badge_awards") awarded_by = models.ForeignKey( User, null=True, blank=True, related_name="awarded_badges_to_team", on_delete=models.SET_NULL, ) awarded_at = models.DateTimeField(auto_now_add=True) reason = models.TextField(blank=True, null=True) + class Meta: + constraints = [ + models.UniqueConstraint( + fields=["team", "badge", "user"], + name="unique_team_badge_user" + ) + ] + def __str__(self): return f"{self.team} - {self.badge.title}"website/feed_signals.py (3)
273-273: Duplicate logger declaration.
loggeris already defined at line 29. This redeclaration is redundant and could cause confusion.🔎 Proposed fix
-logger = logging.getLogger(__name__)
402-409: Performance issue: sorting all organizations in memory for rank comparison.
evaluate_team_badgesfetches all organizations and computes an activity score for each one in Python. With many organizations, this causes O(n) queries and O(n log n) sorting per evaluation. Consider using database-level aggregation or caching scores.🔎 Proposed optimization
elif metric == "team_top_activity_rank": # Check if this team has the highest score without loading all teams team_score = get_team_activity_score(team) # Only award if we can confirm this is top (or use cached leaderboard) higher_exists = Organization.objects.annotate( # This would require a custom annotation or raw SQL # For now, consider caching the top team periodically ).filter(activity_score__gt=team_score).exists() if not higher_exists: award_team_badge(team, badge, reason="Top activity team") else: revoke_team_badge(team, badge)Alternatively, run this ranking check in a periodic task rather than on every contribution.
458-468: Duplicate badge evaluation when issue is closed.When an issue is closed,
issue_updatedevaluates badges forinstance.user's team (lines 460-462) and then again forinstance.closed_by's team (lines 467-468). If the user and closer are on the same team, the evaluation runs twice unnecessarily.🔎 Proposed fix to avoid duplicate evaluation
@receiver(post_save, sender=Issue) def issue_updated(sender, instance, **kwargs): - team = get_user_team(instance.user) - evaluate_team_badges(team) - evaluate_user_team_badges(team) - - if instance.status != "closed" or not instance.closed_by: - return - - team = get_user_team(instance.closed_by) - evaluate_team_badges(team) + teams_to_evaluate = set() + + if instance.user: + user_team = get_user_team(instance.user) + if user_team: + teams_to_evaluate.add(user_team) + + if instance.status == "closed" and instance.closed_by: + closer_team = get_user_team(instance.closed_by) + if closer_team: + teams_to_evaluate.add(closer_team) + + for team in teams_to_evaluate: + evaluate_team_badges(team) + evaluate_user_team_badges(team)
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
⛔ Files ignored due to path filters (17)
website/static/img/badges/team_badges/challenge_conquerors.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/collaborative_force.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/community_hero.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/consistent_performers.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/dependable_contributor.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/discussion_driven_team.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/discussion_driver.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/early_bird.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/issue_crusher.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/issue_dominators.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/issue_initiator.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/most_active_team.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/pull_request_pro.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/team_mvp.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/team_powerhouse.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/team_support_star.pngis excluded by!**/*.pngwebsite/static/img/badges/team_badges/top_contributor.pngis excluded by!**/*.png
📒 Files selected for processing (36)
.env.example.gitignoreblt/settings.pyblt/urls.pytest_duplicate_checker.pywebsite/admin.pywebsite/feed_signals.pywebsite/fixtures/team_badges.jsonwebsite/forms.pywebsite/management/commands/fetch_discord_servers.pywebsite/management/commands/update_github_issues.pywebsite/management/commands/update_repos_dynamic.pywebsite/migrations/0261_badge_scope_teambadge.pywebsite/migrations/0262_alter_badge_scope.pywebsite/migrations/0263_alter_badge_scope.pywebsite/migrations/0264_teambadge_user_alter_userbadge_awarded_by.pywebsite/models.pywebsite/templates/404.htmlwebsite/templates/badge_user_list.htmlwebsite/templates/badges.htmlwebsite/templates/features.htmlwebsite/templates/home.htmlwebsite/templates/includes/header.htmlwebsite/templates/includes/sidenav.htmlwebsite/templates/profile.htmlwebsite/templates/team_overview.htmlwebsite/tests/test_github_commands.pywebsite/tests/test_slack_commands.pywebsite/tests/test_team_badges.pywebsite/views/Simulation.pywebsite/views/company.pywebsite/views/core.pywebsite/views/organization.pywebsite/views/slackbot.pywebsite/views/teams.pywebsite/views/user.py
🧰 Additional context used
🧬 Code graph analysis (10)
website/views/core.py (2)
website/models.py (1)
Badge(1658-1678)website/api/views.py (2)
filter(375-414)filter(844-911)
website/views/teams.py (1)
website/models.py (3)
Badge(1658-1678)TeamBadge(1697-1712)Organization(181-289)
website/tests/test_team_badges.py (1)
website/models.py (2)
Badge(1658-1678)TeamBadge(1697-1712)
website/views/user.py (1)
website/models.py (1)
TeamBadge(1697-1712)
website/migrations/0264_teambadge_user_alter_userbadge_awarded_by.py (3)
website/migrations/0261_badge_scope_teambadge.py (1)
Migration(8-41)website/migrations/0262_alter_badge_scope.py (1)
Migration(6-22)website/migrations/0263_alter_badge_scope.py (1)
Migration(6-22)
blt/urls.py (2)
website/views/teams.py (1)
assign_team_member_badge(361-402)website/views/core.py (1)
badge_list(1457-1471)
website/admin.py (1)
website/models.py (1)
TeamBadge(1697-1712)
website/migrations/0262_alter_badge_scope.py (3)
website/migrations/0261_badge_scope_teambadge.py (1)
Migration(8-41)website/migrations/0263_alter_badge_scope.py (1)
Migration(6-22)website/migrations/0264_teambadge_user_alter_userbadge_awarded_by.py (1)
Migration(8-38)
website/feed_signals.py (1)
website/models.py (8)
Contribution(1438-1465)Hunt(540-573)Issue(590-739)Organization(181-289)TeamBadge(1697-1712)UserBadge(1681-1695)UserProfile(896-1109)Badge(1658-1678)
website/forms.py (1)
website/models.py (2)
Badge(1658-1678)TeamBadge(1697-1712)
🪛 dotenv-linter (4.0.0)
.env.example
[warning] 36-36: [ExtraBlankLine] Extra blank line detected
(ExtraBlankLine)
⏰ 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). (2)
- GitHub Check: Run Tests
- GitHub Check: docker-test
🔇 Additional comments (30)
website/views/organization.py (1)
2575-2575: Approved: Formatting consolidation of exclude clause.The single-argument
.exclude(path="/organizations/")consolidation is cleaner and maintains identical functionality. No behavioral changes.website/views/slackbot.py (1)
430-430: Formatting change approved.The newline adjustment at the end of the file is fine; the method not allowed response is correct.
website/tests/test_slack_commands.py (1)
4-4: Formatting change approved.The blank line after the module docstring follows PEP 257 conventions; test suite is well-structured with comprehensive coverage of success and error scenarios.
website/tests/test_github_commands.py (1)
5-6: LGTM!The
timedeltaimport is correctly placed and is used throughout the test file for mocking timestamps and date calculations..gitignore (1)
28-28: LGTM!Adding
*.debto ignore Debian package files is a sensible addition to prevent build artifacts from being tracked.test_duplicate_checker.py (1)
9-9: No concerns.Trivial whitespace change with no functional impact.
website/management/commands/fetch_discord_servers.py (1)
108-112: LGTM!The multi-line formatting improves readability without changing the logic.
website/management/commands/update_repos_dynamic.py (1)
381-416: LGTM!The multi-line formatting for
closed_atandmerged_atconditional expressions improves readability while preserving the original logic.website/views/company.py (1)
2042-2046: LGTM!The multi-line formatting improves readability of the conditional avatar access.
website/views/Simulation.py (2)
174-176: LGTM!Formatting change improves readability of the conditional message.
213-217: LGTM!Formatting change improves readability of the conditional message.
website/forms.py (1)
446-476: LGTM!The
ReminderSettingsFormis well-implemented:
- Proper
TimeFieldwith multiple input formats for flexibility- Timezone choices populated from
pytz.common_timezones- Helpful user-facing messages about the 15-minute notification delay
- Consistent widget styling with the rest of the codebase
website/migrations/0264_teambadge_user_alter_userbadge_awarded_by.py (1)
1-38: Migration wiring for badge→user relations looks consistentDependencies and FK definitions for
teambadge.useranduserbadge.awarded_bymatch the described model changes (AUTH_USER_MODEL, nullable, properrelated_name). No issues from a schema/migration standpoint.website/templates/home.html (1)
1142-1147: Home “Badges” card correctly targetsuser_badgesUpdating this tile to
{% url 'user_badges' %}keeps home navigation consistent with the new user/team badge routes.website/templates/badge_user_list.html (1)
71-75: “Back to Badges” now aligned withuser_badgesrouteThe back link correctly returns users to the user badges page, matching the new routing scheme.
website/templates/features.html (1)
191-193: Badges feature card correctly targetsuser_badgesRouting this CTA to
{% url 'user_badges' %}is consistent with the new user/team badge separation.website/templates/profile.html (1)
497-507: Badge header link touser_badgeslooks correctUsing the
user_badgesURL name here matches the updated routing while keeping the underlying/badges/path stable. No issues from a routing or template standpoint.website/migrations/0262_alter_badge_scope.py (1)
1-22: Badge.scope migration is consistent with the modelAdding
"topuser_team"to choices and bumpingmax_lengthto 20 aligns withBadge.BADGE_SCOPESinwebsite.models.Badge. This fits cleanly in the 0261→0262→0263 migration chain.blt/urls.py (2)
329-342: New import forassign_team_member_badgeis appropriateImporting
assign_team_member_badgealongside the other team views cleanly exposes it for the new route additions below; nothing to change here.
686-689: URL name change touser_badges— verified no remainingbadgesreferencesThe rename is safe; no remaining
reverse("badges")or{% url 'badges' %}references found in the codebase.website/views/teams.py (1)
360-402: The badge assignment view logic is sound.The view correctly:
- Validates team membership and admin rights before allowing badge assignment.
- Uses
get_object_or_404for safe object retrieval.- Checks for existing badge assignment before creating a duplicate.
- Provides user feedback via messages.
One minor note: the
available_badgeson line 45 filters onlytype="manual"badges, but this view doesn't validate that the selected badge is of type "manual". Consider adding validation to prevent assignment of automatic badges.website/views/user.py (1)
430-433: Chaining different model types may cause template issues.
user_badgesis a QuerySet ofUserBadgeobjects andteam_badgesis a QuerySet ofTeamBadgeobjects. Whilechain()works to combine them, these models have different attributes (e.g.,UserBadgehas noteamfield,TeamBadgehas no direct user relationship pattern asUserBadge).Ensure the template accessing
user_badgeshandles both types gracefully, or consider normalizing the data structure.Also, minor style: add a space after
=on line 430.- team_badges =TeamBadge.objects.filter(user=user) - user_badges = chain(user_badges, team_badges)#combining them + team_badges = TeamBadge.objects.filter(user=user) + user_badges = chain(user_badges, team_badges) # combining themwebsite/admin.py (1)
1154-1159: LGTM!The
TeamBadgeAdminconfiguration follows the existingUserBadgeAdminpattern and provides appropriate list display, filtering, and search capabilities. The registration is correct.Also applies to: 1182-1182
website/templates/404.html (1)
122-133: LGTM!The badges section is correctly split into "User Badges" and "Team Badges" with appropriate URL references. The styling is consistent with other items in the section.
Minor note: With 7 items now in this grid (vs 6 columns at
xl:grid-cols-6), the last item will wrap to a new row. This may be intentional, but verify the visual layout is acceptable.website/migrations/0261_badge_scope_teambadge.py (1)
1-41: LGTM!This migration correctly:
- Adds the
scopefield to theBadgemodel with appropriate choices and default.- Creates the
TeamBadgemodel with proper foreign key relationships and cascading deletes.- Uses
SET_NULLforawarded_byto preserve badge records if the awarder is deleted.The
max_length=10forscopeis corrected to20in the subsequent migration (0262) to accommodate the "topuser_team" value.website/models.py (1)
1663-1673: LGTM on the badge scoping implementation.The addition of
BADGE_SCOPESand thescopefield provides a clean way to differentiate between user, team, and top-user badges. The default of"user"ensures backward compatibility with existing badges.Minor formatting nit: the comment on line 1667 has inconsistent spacing (
"topuser_team","Topuser Team"), but this is cosmetic.website/templates/badges.html (1)
46-72: Clean badge card implementation with proper fallback.The conditional rendering for badge icons with a gradient placeholder fallback is well-implemented. The use of the first letter of the title as a visual identifier is a nice touch.
website/templates/team_overview.html (1)
45-79: Team badges section is well-structured.The team badges display with icon, title, date, and optional reason is clean and provides good user feedback with the empty state message.
website/feed_signals.py (2)
276-294: Team member lookup logic is clear and functional.The helper functions
get_user_teamandget_team_memberscorrectly handle the admin and managers relationships, with proper handling of None cases and use ofdistinct()to avoid duplicates.
356-373: Badge award/revoke functions are well-implemented.The
award_team_badgefunction correctly checks for existing badges before creating new ones, preventing duplicates at the application level. The logging provides good visibility into badge operations.Note: Consider adding a database-level unique constraint on TeamBadge (as mentioned in the models.py review) to handle race conditions.
|
@coderabbitai generate docstrings |
✅ Actions performedInitiated docstring generation; will generate only if new commits exist. |
|
Note Docstrings generation - SUCCESS |
Docstrings generation was requested by @karunarapolu. * #5368 (comment) The following files were modified: * `website/feed_signals.py` * `website/forms.py` * `website/management/commands/fetch_discord_servers.py` * `website/management/commands/update_github_issues.py` * `website/management/commands/update_repos_dynamic.py` * `website/models.py` * `website/tests/test_team_badges.py` * `website/views/Simulation.py` * `website/views/company.py` * `website/views/core.py` * `website/views/organization.py` * `website/views/slackbot.py` * `website/views/teams.py` * `website/views/user.py`
|
💬 Reminder: Unresolved Conversations Hi @karunarapolu! This pull request has 14 unresolved conversations that need to be addressed. Please review and resolve the pending discussions so we can move forward with merging this PR. Thank you! 🙏 |
❌ Pre-commit checks failedThe pre-commit hooks found issues that need to be fixed. Please run the following commands locally to fix them: # Install pre-commit if you haven't already
pip install pre-commit
# Run pre-commit on all files
pre-commit run --all-files
# Or run pre-commit on staged files only
pre-commit runAfter running these commands, the pre-commit hooks will automatically fix most issues. 💡 Tip: You can set up pre-commit to run automatically on every commit by running: pre-commit installPre-commit outputFor more information, see the pre-commit documentation. |
❌ Tests failedThe Django tests found issues that need to be fixed. Please review the test output below and fix the failing tests. How to run tests locally# Install dependencies
poetry install --with dev
# Run all tests
poetry run python manage.py test
# Run tests with verbose output
poetry run python manage.py test -v 3
# Run a specific test
poetry run python manage.py test app.tests.TestClass.test_methodTest outputFor more information, see the Django testing documentation. |
Fixes issue #2575
Design Achievement Badges for Team Overview - Award and Display Team & User Milestones
Overview
This PR implements a comprehensive achievement badge system for teams on the Team Overview Dashboard. Teams and individual team members can now earn badges for milestones such as "Top Contributor," "Early Bird," and other achievement categories. Badges are displayed prominently on the Team Overview Dashboard and user profiles.
Features Implemented
1. Team Badge Model & Data Structure
TeamBadge- Associates badges with teams and optionally with individual users within teamsteam- Team-level achievementstopuser_team- Individual user achievements within a team context2. Badge Award System
Implemented in
feed_signals.py3. Admin Interface & Management
4. UI/UX Components
Team Overview Dashboard (
team_overview.html)User Profile
5. Automatic Badge Evaluation
Implemented via
evaluate_team_badges()andevaluate_user_team_badges():post_saveon Contribution model)6. Testing
Test Coverage
Comprehensive test suite in
website/tests/test_team_badges.py:7. Json file of the badges in website>fixtures>team_badges.json
8. Icons for badges in website>static>img>badges>team_badges
Badges should be manually added in production database inside Badges model for the team badges to work!!
Summary by CodeRabbit
New Features
UI Updates
Tests
Migrations
✏️ Tip: You can customize this high-level summary in your review settings.