fix(analytics): use rolling 7-day window for WAU calculation#490
Conversation
Previously WAU was calculated using non-overlapping weekly buckets. Now it uses a proper rolling 7-day window for each day, showing how WAU changes day-over-day. Definition: Users with workspace_created events on 3+ distinct days within the rolling 7-day window ending on each report date. Also updates WAUTrendChart to use 'date' field instead of 'week'. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WalkthroughThis change refactors the Weekly Active Users (WAU) metric calculation from weekly aggregation to a rolling 7-day window. The backend analytics query now returns per-date data and fills missing dates with zero counts. The data contract is updated to reflect Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 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.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/trpc/src/router/analytics/analytics.ts (1)
146-155: Potential timezone mismatch between SQL and JavaScript date handling.The SQL query uses
toDate(now())which operates in the ClickHouse server's timezone, while JavaScript'stoISOString().split("T")[0]always produces UTC dates. If the server timezone differs from UTC, the date strings may not align, causing map lookups to return 0 for valid dates.Consider using
formatDateTime(toDate(now()), '%Y-%m-%d')in SQL to match the format, or use a consistent timezone approach:Option 1: Use formatDateTime in SQL for explicit date format
const { results } = await executeHogQLQuery<[string, number][]>(` SELECT - report_date as date, + formatDateTime(report_date, '%Y-%m-%d') as date, count(DISTINCT person_id) as wauOption 2: Alternatively, align JS to local timezone
- const dateStr = date.toISOString().split("T")[0] as string; + const dateStr = date.toLocaleDateString("sv-SE"); // ISO format in local tzapps/admin/src/app/(dashboard)/components/WAUTrendChart/WAUTrendChart.tsx (1)
52-55: Consider updating description text to reflect rolling window semantics.The description says "this week" but the metric now uses a rolling 7-day window ending on the most recent date. This could be slightly confusing to users expecting calendar week alignment.
Suggested text update
<div> <CardTitle>Weekly Active Users</CardTitle> <CardDescription> - {currentWAU} users active 3+ days this week + {currentWAU} users active 3+ days (rolling 7-day window) </CardDescription> </div>
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/admin/src/app/(dashboard)/components/WAUTrendChart/WAUTrendChart.tsxpackages/trpc/src/router/analytics/analytics.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Avoid using any type in TypeScript - maintain type safety unless absolutely necessary
Files:
apps/admin/src/app/(dashboard)/components/WAUTrendChart/WAUTrendChart.tsxpackages/trpc/src/router/analytics/analytics.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Run Biome for formatting, linting, import organization, and safe fixes at the root level using bun run lint:fix
Files:
apps/admin/src/app/(dashboard)/components/WAUTrendChart/WAUTrendChart.tsxpackages/trpc/src/router/analytics/analytics.ts
**/{components,features}/**/[!.]*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Organize project structure with one folder per component: ComponentName/ComponentName.tsx with index.ts barrel export
Files:
apps/admin/src/app/(dashboard)/components/WAUTrendChart/WAUTrendChart.tsx
**/{components,features}/**/*.{ts,tsx,test.ts,test.tsx,stories.tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Files:
apps/admin/src/app/(dashboard)/components/WAUTrendChart/WAUTrendChart.tsx
**/*.{tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Use React + TailwindCSS v4 + shadcn/ui for UI development
Files:
apps/admin/src/app/(dashboard)/components/WAUTrendChart/WAUTrendChart.tsx
**/{components,features}/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
**/{components,features}/**/*.tsx: Nest components in parent's components/ folder if used only once, promote to highest shared parent's components/ if used 2+ times
Use one component per file - do not combine multiple components in a single file
Files:
apps/admin/src/app/(dashboard)/components/WAUTrendChart/WAUTrendChart.tsx
⏰ 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). (6)
- GitHub Check: Deploy Admin
- GitHub Check: Deploy Marketing
- GitHub Check: Deploy API
- GitHub Check: Deploy Web
- GitHub Check: Deploy Docs
- GitHub Check: Build
🔇 Additional comments (3)
packages/trpc/src/router/analytics/analytics.ts (1)
108-140: Rolling 7-day WAU query implementation looks correct.The SQL logic correctly:
- Generates report dates for the requested range
- Cross-joins with activity data within the lookback window
- Filters for users with 3+ distinct active days in each 7-day window
- Groups and counts per report date
One consideration: The window condition
activity_date > report_date - 7 AND activity_date <= report_datecreates a 7-day inclusive window ending on report_date. This aligns with the PR description.apps/admin/src/app/(dashboard)/components/WAUTrendChart/WAUTrendChart.tsx (2)
20-23: Data contract updated correctly to align with backend changes.The interface now reflects the per-date data structure returned by the updated
getWAUTrendAPI.
76-88: XAxis dataKey correctly updated to match new data shape.The chart configuration properly consumes the
datefield from the updated API response.
Summary
Before vs After
Before: Weekly buckets (e.g., Week 1: days 0-7, Week 2: days 8-14)
After: Rolling window per day (e.g., Dec 23: days 17-23, Dec 22: days 16-22)
Definition
WAU = Users who had
workspace_createdevents on 3+ distinct days within a rolling 7-day window.Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.