Conversation
Previously, user.current_streak was only updated when creating new entries. This caused the dashboard to show stale streak values when users stopped writing for 2+ days. Changes: - Add calculate_current_streak() method to DashboardView - Calculate streak from actual entries in real-time - Streak shows 0 if last entry was 2+ days ago - Streak continues if last entry was today or yesterday - Preserve longest_streak from user model (historical record) Adds 9 comprehensive tests for the new streak calculation logic.
📝 WalkthroughWalkthroughAdds real-time current_streak calculation (optionally anchored to yesterday) used by DashboardView and a new integration test module validating streak behavior across timezones, gaps, empty entries, and combinations of historical/current-day entries. Changes
Sequence DiagramsequenceDiagram
participant Client
participant DashboardView as DashboardView
participant StreakUtil as recalculate_user_streak
participant EntryModel as EntryModel
participant Database as Database
Client->>DashboardView: GET /api/v1/dashboard/
DashboardView->>StreakUtil: recalculate_user_streak(user, allow_yesterday=True)
StreakUtil->>EntryModel: Query entries for user (word_count>0)
EntryModel->>Database: SELECT entries ORDER BY created
Database-->>EntryModel: Return entries
EntryModel-->>StreakUtil: Entry list (dates filtered)
StreakUtil->>StreakUtil: Determine anchor (today or yesterday) and compute streak
StreakUtil-->>DashboardView: current_streak
DashboardView->>Client: Return dashboard stats with current_streak
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@apps/api/tests/test_dashboard_streak.py`:
- Around line 156-158: Update the misleading inline comment above the
EntryFactory call in test_dashboard_streak.py: replace the incorrect timezone
conversion ("2025-01-13 17:00 UTC = 2025-01-14 09:00 LA time") with the correct
conversion reflecting LA = UTC-8 (e.g., "2025-01-13 17:00 UTC = 2025-01-13 09:00
LA time") so the comment correctly describes why EntryFactory(user=user,
created_at=timezone.now() - timedelta(days=1, hours=8)) yields an entry on Jan
13 in LA time.
In `@apps/api/views.py`:
- Line 226: Remove the redundant local import "from apps.journal.models import
Entry" in apps/api/views.py (it's already imported at module level as Entry);
locate the inline import inside the function or block and delete that line so
the code uses the existing top-level Entry import and avoids duplicate imports.
🧹 Nitpick comments (3)
apps/api/views.py (2)
30-30: Consider grouping Django imports together.The
TruncDateimport fromdjango.db.models.functionsshould be grouped with other Django imports (lines 13-21) for better organization.♻️ Suggested import organization
Move line 30 up to group with other Django imports:
from django.db.models import Sum, Count, Q +from django.db.models.functions import TruncDate from django.db import transaction from django.core.cache import cache from django.utils import timezone from apps.journal.models import Entry, FeaturedEntry from apps.journal.utils import ( get_random_quote, get_user_local_date, get_today_date_range, parse_tags, ) -from django.db.models.functions import TruncDate from apps.api.serializers import (
233-245: Consider optimizing to avoid potential double query evaluation.The queryset is evaluated twice: once for
exists()(line 241) and once when iterating to build thedateslist (line 245). You could simplify this by fetching the list directly and checking its length.♻️ Suggested optimization
# Get all days with entries (with word_count > 0) - entry_dates = ( + dates = list( Entry.objects.filter(user=user, word_count__gt=0) .annotate(day=TruncDate('created_at', tzinfo=user_tz)) - .values('day') - .distinct() + .values_list('day', flat=True) .order_by('day') + .distinct() ) - if not entry_dates.exists(): + if not dates: return 0 - - # Get unique dates as a list - dates = sorted(set(item['day'] for item in entry_dates))apps/api/tests/test_dashboard_streak.py (1)
18-21: Add@pytest.mark.streakdomain marker per coding guidelines.The coding guidelines specify using domain markers for tests. Since these tests cover streak functionality, add the
@pytest.mark.streakmarker.♻️ Suggested fix
`@pytest.mark.integration` +@pytest.mark.streak `@pytest.mark.django_db` class TestDashboardStreakRealTime: """Tests for real-time streak calculation in dashboard."""As per coding guidelines: "Use pytest with markers (
@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.slow) and domain markers (@pytest.mark.encryption,@pytest.mark.streak,@pytest.mark.statistics)"
| # Entry from "yesterday" in LA timezone (which is 2 days ago UTC) | ||
| # 2025-01-13 17:00 UTC = 2025-01-14 09:00 LA time (yesterday for LA user) | ||
| EntryFactory(user=user, created_at=timezone.now() - timedelta(days=1, hours=8)) |
There was a problem hiding this comment.
Fix incorrect comment - timezone math is wrong.
The comment states "2025-01-13 17:00 UTC = 2025-01-14 09:00 LA time" but LA is UTC-8, so the correct conversion is:
- 2025-01-13 17:00 UTC = 2025-01-13 09:00 LA time
The test assertion is still correct (entry is on Jan 13 LA time, which is "yesterday" when LA's current date is Jan 14), but the comment is misleading.
📝 Suggested comment fix
# Entry from "yesterday" in LA timezone (which is 2 days ago UTC)
- # 2025-01-13 17:00 UTC = 2025-01-14 09:00 LA time (yesterday for LA user)
+ # 2025-01-13 17:00 UTC = 2025-01-13 09:00 LA time (yesterday for LA user since LA is on Jan 14)
EntryFactory(user=user, created_at=timezone.now() - timedelta(days=1, hours=8))🤖 Prompt for AI Agents
In `@apps/api/tests/test_dashboard_streak.py` around lines 156 - 158, Update the
misleading inline comment above the EntryFactory call in
test_dashboard_streak.py: replace the incorrect timezone conversion ("2025-01-13
17:00 UTC = 2025-01-14 09:00 LA time") with the correct conversion reflecting LA
= UTC-8 (e.g., "2025-01-13 17:00 UTC = 2025-01-13 09:00 LA time") so the comment
correctly describes why EntryFactory(user=user, created_at=timezone.now() -
timedelta(days=1, hours=8)) yields an entry on Jan 13 in LA time.
Code reviewFound 2 issues:
All 9 tests in this file exercise streak logic, but the class only declares QuietPage/apps/api/tests/test_dashboard_streak.py Lines 19 to 21 in d4fc7e1
The commit message is Lines 207 to 268 in d4fc7e1 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
Problem
Dashboard showed stale streak values when users stopped writing. The
user.current_streakwas only updated when creating new entries.Solution
Calculate current streak in real-time from actual entries:
longest_streakstill comes from user model (historical)Changes
calculate_current_streak()method to DashboardViewTesting
Summary by CodeRabbit
New Features
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.