Skip to content

feat(admin): add paid product activity chart#2094

Merged
riderx merged 6 commits into
mainfrom
codex/admin-paid-product-activity-chart
May 10, 2026
Merged

feat(admin): add paid product activity chart#2094
riderx merged 6 commits into
mainfrom
codex/admin-paid-product-activity-chart

Conversation

@riderx
Copy link
Copy Markdown
Member

@riderx riderx commented May 10, 2026

Summary (AI generated)

  • Added an admin dashboard line chart comparing paying clients, Builder-active paying clients, and Live Updates-active paying clients over time.
  • Stored the Builder and Live Updates 60-day active paying-client counts in public.global_stats during the existing daily snapshot job.
  • Added bun run admin:backfill-paid-product-activity to backfill historical global_stats rows once.
  • Added a $ / % toggle to the churn chart so admins can switch between lost MRR and churn rate.

Motivation (AI generated)

  • Capgo needs a daily view of how many paying clients actively use Builder compared with Live Updates without recalculating historical windows on every dashboard request.
  • Revenue admins also need to inspect churn as either absolute lost revenue or a normalized rate depending on the decision they are making.

Business Impact (AI generated)

  • Makes Builder adoption visible for paying customers, supporting product adoption tracking and prioritization.
  • Keeps the metric in the existing global stats rollup so admin reporting stays cheap to read.
  • Provides a one-off historical backfill path so the chart has past data after deploy.
  • Improves churn analysis by making dollar impact and percentage movement available from the same chart.

Test Plan (AI generated)

  • bun test tests/admin-stats.unit.test.ts tests/logsnag-insights-revenue.unit.test.ts
  • bun run admin:backfill-paid-product-activity --help
  • bunx eslint --no-ignore scripts/backfill_paid_product_activity.ts
  • bunx eslint --no-ignore src/pages/admin/dashboard/revenue.vue supabase/functions/_backend/utils/pg.ts
  • bun lint
  • bun lint:backend
  • bun typecheck
  • bun run lint:deadcode
  • typos package.json scripts/backfill_paid_product_activity.ts
  • git diff --check
  • bun run build
  • Headless browser smoke test for /admin/dashboard

Summary by CodeRabbit

Release Notes

  • New Features

    • Added "Paying Client Product Activity" chart to admin dashboard showing 60-day trends for active paying clients.
  • Chores

    • Added admin backfill script to calculate historical paid product activity data.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: db042158-754b-4056-b337-cf27a7cd3179

📥 Commits

Reviewing files that changed from the base of the PR and between 05a430c and 34ee433.

📒 Files selected for processing (1)
  • supabase/migrations/20260510191550_add_paid_product_activity_to_global_stats.sql
✅ Files skipped from review due to trivial changes (1)
  • supabase/migrations/20260510191550_add_paid_product_activity_to_global_stats.sql

📝 Walkthrough

Walkthrough

This pull request adds 60-day active paying client metrics for both Builder and Live Updates products to the admin dashboard. It includes database schema migration, type definitions, backend calculation logic in the insights function, admin query utilities, dashboard visualization, and a CLI backfill script to populate historical data.

Changes

Paid Product Activity Metrics

Layer / File(s) Summary
Database Schema
supabase/migrations/20260510191550_add_paid_product_activity_to_global_stats.sql
Two integer columns added to public.global_stats: builder_active_paying_clients_60d and live_updates_active_paying_clients_60d, both with DEFAULT 0 and NOT NULL.
Type Definitions
src/types/supabase.types.ts, supabase/functions/_backend/utils/supabase.types.ts
Updated global_stats Row/Insert/Update types to include the two new metrics as required on Row and optional on Insert/Update.
Backend Calculation
supabase/functions/_backend/triggers/logsnag_insights.ts
Added PaidProductActivityStats interface and getPaidProductActivityStats() function that counts distinct paying clients with builder/live-updates activity over 60-day lookback; integrated into getStats() and global_stats upsert payload.
Admin Query Utilities
supabase/functions/_backend/utils/pg.ts
Extended AdminGlobalStatsTrend interface and getAdminGlobalStatsTrend SQL query to select and map the two new metrics with COALESCE defaults.
Dashboard Display
src/pages/admin/dashboard/index.vue, messages/en.json
Extended trend data type, added paidProductActivityTrendSeries computed series, rendered new ChartCard for paid product activity, and added i18n translation key.
Backfill Script & Tooling
scripts/backfill_paid_product_activity.ts, package.json
Implemented CLI script supporting dry-run (default), --apply mode, date-range scoping, batch processing, and automatic database/SSL discovery; wired via admin:backfill-paid-product-activity npm script.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A rabbit hops through metrics bright,
Sixty days of paying light—
Builders dance, live updates thrive,
Dashboard trends now come alive!
Script backfills the data trail,
With bun and SQL, none shall fail. 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat(admin): add paid product activity chart' accurately and concisely summarizes the primary change: adding a new admin dashboard chart for paid product activity metrics.
Description check ✅ Passed The PR description includes a comprehensive summary, motivation, and detailed test plan covering unit tests, CLI validation, linting, type checking, and browser testing. However, it lacks explicit sections matching the template structure (Summary, Test plan, Screenshots, Checklist).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/admin-paid-product-activity-chart

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 SQLFluff (4.1.0)
supabase/migrations/20260510191550_add_paid_product_activity_to_global_stats.sql

User Error: No dialect was specified. You must configure a dialect or specify one on the command line using --dialect after the command. Available dialects:
ansi, athena, bigquery, clickhouse, databricks, db2, doris, duckdb, exasol, flink, greenplum, hive, impala, mariadb, materialize, mysql, oracle, postgres, redshift, snowflake, soql, sparksql, sqlite, starrocks, teradata, trino, tsql, vertica


Comment @coderabbitai help to get the list of available commands and usage tips.

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq Bot commented May 10, 2026

Merging this PR will not alter performance

✅ 43 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing codex/admin-paid-product-activity-chart (34ee433) with main (4d3bad4)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@riderx riderx marked this pull request as ready for review May 10, 2026 16:25
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

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.

🧹 Nitpick comments (1)
scripts/backfill_paid_product_activity.ts (1)

126-133: 💤 Low value

Consider adding query timeout for long-running backfills.

The database client doesn't set a statement_timeout or query_timeout. For large datasets, a query could potentially run indefinitely if there are database issues.

♻️ Optional: Add query timeout
 function createPgClient(databaseUrl: string, env: Record<string, string | undefined>) {
   const host = new URL(databaseUrl).hostname
   const usesLocalDatabase = host === 'localhost' || host === '127.0.0.1' || host === '::1'
   return new PgClient({
     connectionString: databaseUrl,
     ssl: usesLocalDatabase ? false : { rejectUnauthorized: !shouldAllowSelfSignedPgCertificate(env, databaseUrl) },
+    statement_timeout: 300000, // 5 minutes per query
   })
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/backfill_paid_product_activity.ts` around lines 126 - 133, The
createPgClient factory currently returns a PgClient without any query timeout;
add a configurable query timeout to prevent runaway backfill queries by having
createPgClient accept a timeout (or read from env) and, after creating and
connecting the PgClient, execute a SET statement to apply a default
statement_timeout (e.g., await client.query(`SET statement_timeout =
${timeoutMs}`)) before running backfill queries; update callers to pass a
sensible timeout and keep shouldAllowSelfSignedPgCertificate and existing ssl
behavior unchanged (refer to createPgClient, PgClient, and
shouldAllowSelfSignedPgCertificate to locate the change).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@scripts/backfill_paid_product_activity.ts`:
- Around line 126-133: The createPgClient factory currently returns a PgClient
without any query timeout; add a configurable query timeout to prevent runaway
backfill queries by having createPgClient accept a timeout (or read from env)
and, after creating and connecting the PgClient, execute a SET statement to
apply a default statement_timeout (e.g., await client.query(`SET
statement_timeout = ${timeoutMs}`)) before running backfill queries; update
callers to pass a sensible timeout and keep shouldAllowSelfSignedPgCertificate
and existing ssl behavior unchanged (refer to createPgClient, PgClient, and
shouldAllowSelfSignedPgCertificate to locate the change).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ba0adf37-bf2a-4474-81aa-67126f18c228

📥 Commits

Reviewing files that changed from the base of the PR and between b5b42ae and f790649.

📒 Files selected for processing (9)
  • messages/en.json
  • package.json
  • scripts/backfill_paid_product_activity.ts
  • src/pages/admin/dashboard/index.vue
  • src/types/supabase.types.ts
  • supabase/functions/_backend/triggers/logsnag_insights.ts
  • supabase/functions/_backend/utils/pg.ts
  • supabase/functions/_backend/utils/supabase.types.ts
  • supabase/migrations/20260510171606_add_paid_product_activity_to_global_stats.sql

@sonarqubecloud
Copy link
Copy Markdown

@riderx riderx merged commit 8f67630 into main May 10, 2026
70 of 71 checks passed
@riderx riderx deleted the codex/admin-paid-product-activity-chart branch May 10, 2026 19:55
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.

1 participant