Conversation
- Implemented loading of per-day email status counts for the last 30 days in the email overview. - Enhanced the ActivityBarChart component to track hovered data points, adjusting opacity for non-hovered bars. - Updated the StackedTooltip to display a 7-day average for email metrics. - Refactored the metrics page to utilize the new stacked data points and improved layout for better user experience.
- Introduced a new function to load monthly active users (MAU) from ClickHouse, aggregating user activity over the last 30 days. - Updated the auth overview to include the MAU metric. - Enhanced the metrics page to support hover interactions for visitors and revenue data, allowing users to switch between different chart views with fade transitions. - Added new data types for visitors and revenue hover charts to improve data representation in the dashboard.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds DesignAnalyticsCard UI primitives and infinite-scroll utilities; refactors dashboard metrics and email pages to use them; extends backend internal metrics route with auth/payments/email/analytics overview loaders (ClickHouse-backed with dev fallbacks); expands Prisma seed data (users/subscriptions/emails) and stabilizes e2e metrics tests via polling. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Dashboard Client
participant MetricsAPI as Metrics Route
participant Prisma as Prisma DB
participant ClickHouse as ClickHouse
participant Fallback as Dev Fallback Generator
Client->>MetricsAPI: GET /internal/metrics
MetricsAPI->>Prisma: Load auth, payments, email records
Prisma-->>MetricsAPI: DB rows
MetricsAPI->>ClickHouse: Query analytics/DAU/MAU and aggregates
alt ClickHouse responds
ClickHouse-->>MetricsAPI: Analytics aggregates
else ClickHouse missing/unavailable
MetricsAPI->>Fallback: generateDevDauSplit()/generateDevAnalyticsOverview()
Fallback-->>MetricsAPI: Synthetic aggregates
end
MetricsAPI->>MetricsAPI: Compose auth_overview, payments_overview, email_overview, analytics_overview
MetricsAPI-->>Client: JSON response with composed overviews
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ❌ 3❌ Failed checks (2 warnings, 1 inconclusive)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
- Added a `CustomDateRange` type and updated the `TimeRange` to include a 'custom' option for date filtering. - Implemented shared helper functions for parsing and normalizing date inputs to ensure accurate date handling in charts. - Updated various components, including `MetricsPage`, `line-chart`, and `metrics-page`, to support custom date ranges and maintain synchronization across the dashboard. - Improved scrollbar styling in `globals.css` for better user experience.
- Replaced instances of custom GlassCard components with the new DesignAnalyticsCard across various pages, including email drafts, email themes, and metrics pages. - Introduced DesignAnalyticsCard for improved chart rendering and tooltip handling, enhancing the overall dashboard interactivity. - Updated the DESIGN-GUIDE.md to include guidelines for using DesignAnalyticsCard and its associated components. - Added new demo data for analytics points to support the updated card functionality.
- Updated the `loadAnalyticsOverview` function to include parameters for anonymous user tracking. - Added queries to retrieve daily visitor counts and total unique visitors from ClickHouse. - Adjusted the metrics returned to include daily visitors and total revenue calculations based on visitor data. - Modified the `MetricsContent` component to handle revenue display logic based on available data, improving overall dashboard accuracy.
…s and revenue metrics - Added `showVisitors` and `showRevenue` props to the `ComposedAnalyticsChart` for better control over displayed metrics. - Updated logic to conditionally render visitor and revenue lines based on the new props. - Introduced `SetupAppPrompt` component in `metrics-page` to guide users in enabling analytics and payments features. - Adjusted `MetricsContent` to handle data visibility based on the availability of analytics and payments apps.
…itional rendering - Added `fullBleed` and `wrapHeaderInCard` props to the `PageLayout` component for improved layout flexibility. - Updated `ComposedAnalyticsChart` to utilize `useMemo` for tagged data points, enhancing performance and conditional rendering of visitor and revenue metrics based on new props. - Improved tooltip display logic in `ComposedAnalyticsChart` to handle visibility based on user preferences for visitors and revenue data.
There was a problem hiding this comment.
Pull request overview
Revamps the dashboard project overview (metrics page) into a more analytics-focused layout, backed by an expanded internal metrics API that returns cross-product aggregate groups (auth/payments/email/analytics) and shared UI primitives for chart cards and infinite-scroll lists.
Changes:
- Expand
/api/v1/internal/metricsto returnauth_overview,payments_overview,email_overview, andanalytics_overview, including dev-mode synthetic fallbacks for ClickHouse-dependent series. - Introduce
DesignAnalyticsCard(+ header/legend/infinite list helpers) and migrate multiple dashboard pages and the overview to use it. - Update e2e coverage for the internal metrics endpoint and extend dummy seed data for more realistic overview surfaces.
Reviewed changes
Copilot reviewed 14 out of 16 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
claude/CLAUDE-KNOWLEDGE.md |
Adds internal notes/Q&A for metrics endpoint expansion and overview chart behavior. |
apps/e2e/tests/backend/endpoints/api/v1/internal-metrics.test.ts |
Stabilizes anonymous-exclusion testing and adds coverage for new aggregate groups. |
apps/dashboard/src/components/design-components/index.ts |
Re-exports the new analytics card module. |
apps/dashboard/src/components/design-components/analytics-card.tsx |
New shared analytics card shell + legend + infinite list hook/component. |
apps/dashboard/src/app/globals.css |
Adds global scrollbar styling. |
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/page-layout.tsx |
Adds fullBleed and wrapHeaderInCard options for overview-style layout. |
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/emails/page-client.tsx |
Migrates email page cards to DesignAnalyticsCard. |
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-themes/page-client.tsx |
Migrates theme page cards to DesignAnalyticsCard and adds a shared section header. |
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-drafts/page-client.tsx |
Migrates to DesignAnalyticsCard and changes drafts page structure. |
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/metrics-page.tsx |
Major redesign of overview layout, hero widget interactions, and new email/referrer cards. |
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/playground/page-client.tsx |
Adds playground controls/demo for DesignAnalyticsCard. |
apps/dashboard/DESIGN-GUIDE.md |
Documents DesignAnalyticsCard and updates guidance against local GlassCard/ChartCard clones. |
apps/backend/src/app/api/latest/internal/metrics/route.tsx |
Adds cross-product aggregates + DAU/team split series + MAU + analytics/email/payments overview loaders. |
apps/backend/prisma/seed.ts |
Adds more realistic dummy users/subscriptions/emails for overview breadth. |
Comments suppressed due to low confidence (1)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-themes/page-client.tsx:182
- The Active Theme header renders "Currently using …" twice (once near the left group and again after the "Active Theme" badge), which looks like an accidental duplication and will clutter the UI. Remove one of the duplicate spans so the header has a single source of truth for that text.
<div className="flex items-center justify-between gap-4">
<div className="flex items-center gap-4">
<SectionHeader icon={Palette} title="Active Theme" />
<span className="text-sm text-muted-foreground">
Currently using <span className="font-medium text-foreground">{selectedThemeData.displayName}</span>
</span>
</div>
<span className="text-xs font-semibold text-foreground uppercase tracking-wider">
Active Theme
</span>
<span className="text-sm text-muted-foreground">
Currently using <span className="font-medium text-foreground">{selectedThemeData.displayName}</span>
</span>
</div>
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Greptile SummaryThis PR is a substantial overview-page revamp adding rich KPIs and analytics sections (auth, payments, email, web analytics) to the metrics endpoint, plus a new Many previously flagged issues have been addressed: the deliverability-rate >100% bug is fixed with Confidence Score: 5/5Safe to merge — all remaining findings are P2 style/hardening concerns that do not block correctness or data integrity. Most previously flagged issues (OOM unbounded queries, deliverability >100%, hardcoded MRR, duplicate style injection) have been addressed. Three new P2 findings remain: the sql-query tool's client-side row truncation not preventing ClickHouse OOM, a duplicate SubscriptionInvoice revenue aggregation, and a hardcoded refund_cents: 0 stub — none of which affect correctness of the primary dashboard flows. apps/backend/src/lib/ai/tools/sql-query.ts (MAX_ROWS_FOR_AI backstop does not enforce limit at the DB level) Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[GET /internal/metrics] --> B[Promise.all]
B --> C[loadTotalUsers\nClickHouse]
B --> D[loadDailyActiveUsers\nClickHouse]
B --> E[loadUsersByCountry\nClickHouse]
B --> F[loadAuthOverview\nPostgres + ClickHouse]
B --> G[loadPaymentsOverview\nPostgres]
B --> H[loadEmailOverview\nPostgres]
B --> I[loadAnalyticsOverview\nClickHouse + Postgres]
B --> J[loadDailyRevenue\nPostgres]
F --> F1[loadDailyActiveUsersSplit]
F --> F2[loadDailyActiveTeamsSplit]
F --> F3[loadMonthlyActiveUsers]
I --> I1[loadSessionReplayAggregates]
G --> G2[revenue_cents - SubscriptionInvoice SUM]
I1 --> I2[total_revenue_cents - SubscriptionInvoice SUM DUPLICATE]
J --> K[Stitch daily_revenue into analytics_overview]
K --> L[200 OK Response]
style G2 fill:#ffd,stroke:#aa0
style I2 fill:#ffd,stroke:#aa0
Prompt To Fix All With AIThis is a comment left during a code review.
Path: apps/backend/src/lib/ai/tools/sql-query.ts
Line: 40-45
Comment:
**`MAX_ROWS_FOR_AI` truncates after loading all rows into memory**
The comment describes this as a "backstop if LIMIT is missing," but `resultSet.json()` eagerly loads every row returned by ClickHouse into the Node.js heap before the slice. A query missing a LIMIT clause (e.g. `SELECT * FROM events`) would still materialise the full result set in memory before being truncated to 50 rows, defeating the backstop for large datasets.
Enforce the cap at the database level instead:
```typescript
const safeQuery = `SELECT * FROM (${query}) LIMIT ${MAX_ROWS_FOR_AI + 1}`;
```
Then remove the `rows.slice(0, MAX_ROWS_FOR_AI)` post-processing, or keep it as a secondary safety net.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: apps/backend/src/app/api/latest/internal/metrics/route.tsx
Line: 397-405
Comment:
**Duplicate all-time revenue aggregation between `loadSessionReplayAggregates` and `loadPaymentsOverview`**
Both functions independently compute the all-time paid `SubscriptionInvoice` sum with identical SQL, resulting in two separate database round-trips that always return the same value. The result is exposed as both `analytics_overview.total_revenue_cents` and `payments_overview.revenue_cents`. If either query's filter diverges in the future, the two fields will silently disagree.
Consider computing this once in `loadPaymentsOverview` and passing the value through to `loadSessionReplayAggregates`.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: apps/backend/src/app/api/latest/internal/metrics/route.tsx
Line: 355-370
Comment:
**`refund_cents` is always hardcoded to `0`**
`loadDailyRevenue` pushes `refund_cents: 0` for every day; no refund query exists. `MetricsDailyRevenuePointSchema` exposes this field, so any dashboard widget reading it will perpetually display $0 in refunds. At minimum a comment should note this is a placeholder, or the field should be omitted from the schema until refund data is actually tracked.
How can I resolve this? If you propose a fix, please make it concise.Reviews (4): Last reviewed commit: "Refactor Analytics Metrics Queries" | Re-trigger Greptile |
…etrics - Adjusted expected values in test snapshots for risk scores related to sign-up, setting both "bot" and "free_trial_abuse" metrics to zero for consistency with recent analytics data updates.
…20 seconds for improved stability. Adjusted polling logic in internal metrics test to ensure accurate comparison of user data while excluding anonymous users.
Summary by CodeRabbit
New Features
Style
Tests
Documentation