Skip to content

fix: serve /data success rate from global_stats#2706

Open
riderx wants to merge 1 commit into
mainfrom
fix/public-metrics-use-global-stats
Open

fix: serve /data success rate from global_stats#2706
riderx wants to merge 1 commit into
mainfrom
fix/public-metrics-use-global-stats

Conversation

@riderx

@riderx riderx commented Jul 16, 2026

Copy link
Copy Markdown
Member

Summary

  • Public /private/website_stats/live_updates was computing a separate Analytics Engine device-day success rate (~70%).
  • Admin global_stats shows ~84%. These are now the same source: success_rate + daily series come from global_stats.
  • Analytics Engine is kept only for failure reasons, platforms, and updater versions (one fewer AE query).
  • Removes duplicate discord_username type fields that broke typecheck on main.

Test plan

  • bunx vitest run tests/public-live-update-metrics.unit.test.ts tests/public-stats.unit.test.ts
  • Deploy API
  • Confirm GET /private/website_stats/live_updates success_rate matches admin Updates success rate
  • Confirm https://capgo.app/data/ KPI matches after deploy + cache TTL

Made with Cursor

Review in cubic

/data was computing a separate Analytics Engine device-day rate (~70%) instead of the admin global_stats success rate (~84%). Use global_stats for success_rate/daily and keep AE only for failure/platform/version breakdowns. Also remove duplicate social username type fields blocking typecheck.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5d4201bf-3d7f-4486-98b4-b581c0e474d2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

@codspeed-hq

codspeed-hq Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 43 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing fix/public-metrics-use-global-stats (d7a4045) with main (18b4392)

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.

@sonarqubecloud

Copy link
Copy Markdown

@riderx riderx marked this pull request as ready for review July 16, 2026 13:49
@cursor

cursor Bot commented Jul 16, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_f2fef751-cbc7-496a-808e-ffed443202f7)

@cursor cursor Bot requested a review from WcaleNieWolny July 16, 2026 13:50

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Risk: medium. Not approving: Cursor Bugbot completed as skipped (usage limit reached) with no clean review signal. Human review is needed before merge.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Approver

@cursor cursor Bot requested a review from Dalanir July 16, 2026 13:50

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Risk: medium. Not approving: Cursor Bugbot completed as skipped (usage limit reached) with no clean review signal, and this public metrics data-source change exceeds the low-risk approval threshold. WcaleNieWolny is already assigned for human review.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Approver External

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 6 files

Confidence score: 3/5

  • In supabase/functions/_backend/private/public_stats.ts, the /live_updates path can include partially completed global_stats rows while admin excludes them, so users may see a transiently incorrect success rate versus admin during shard processing — align the filter logic (including completion criteria like completed_at) before merging.
  • In supabase/functions/_backend/utils/cloudflare.ts, getPublicLiveUpdateMetricsCF now returns only breakdowns and drops success_rate/daily, which can break caller expectations of the full metric contract — either restore those fields or rename/scope the function to match the reduced response before merging.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="supabase/functions/_backend/utils/cloudflare.ts">

<violation number="1" location="supabase/functions/_backend/utils/cloudflare.ts:2601">
P3: Callers can reasonably expect `getPublicLiveUpdateMetricsCF` to return the complete live-update metric contract, but it now returns only breakdowns and omits `success_rate`/`daily`. Renaming it to `getPublicLiveUpdateBreakdownMetricsCF` would keep the exported API aligned with its new responsibility.</violation>
</file>

<file name="supabase/functions/_backend/private/public_stats.ts">

<violation number="1" location="supabase/functions/_backend/private/public_stats.ts:48">
P2: During daily shard processing, `/live_updates` can still show a success rate that differs from admin because this query admits partially completed `global_stats` rows that the admin query excludes. Filtering on `completed_shards` with `REQUIRED_GLOBAL_STATS_SHARDS` keeps the KPI and daily series aligned with admin.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

.select('date_id, success_rate')
.gte('date_id', startDateId)
.lte('date_id', latestCompletedDateId)
.not('success_rate', 'is', null)

@cubic-dev-ai cubic-dev-ai Bot Jul 16, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: During daily shard processing, /live_updates can still show a success rate that differs from admin because this query admits partially completed global_stats rows that the admin query excludes. Filtering on completed_shards with REQUIRED_GLOBAL_STATS_SHARDS keeps the KPI and daily series aligned with admin.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At supabase/functions/_backend/private/public_stats.ts, line 48:

<comment>During daily shard processing, `/live_updates` can still show a success rate that differs from admin because this query admits partially completed `global_stats` rows that the admin query excludes. Filtering on `completed_shards` with `REQUIRED_GLOBAL_STATS_SHARDS` keeps the KPI and daily series aligned with admin.</comment>

<file context>
@@ -33,6 +34,34 @@ export function getLatestCompletedGlobalStatsDateId(referenceDate = new Date())
+    .select('date_id, success_rate')
+    .gte('date_id', startDateId)
+    .lte('date_id', latestCompletedDateId)
+    .not('success_rate', 'is', null)
+    .order('date_id', { ascending: true })
+
</file context>
Suggested change
.not('success_rate', 'is', null)
.contains('completed_shards', [...REQUIRED_GLOBAL_STATS_SHARDS])
Fix with cubic

daily: Array<{ date: string, success_rate: number }>
}

export async function getPublicLiveUpdateMetricsCF(c: Context, referenceDate = new Date()): Promise<PublicLiveUpdateBreakdownMetrics> {

@cubic-dev-ai cubic-dev-ai Bot Jul 16, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Callers can reasonably expect getPublicLiveUpdateMetricsCF to return the complete live-update metric contract, but it now returns only breakdowns and omits success_rate/daily. Renaming it to getPublicLiveUpdateBreakdownMetricsCF would keep the exported API aligned with its new responsibility.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At supabase/functions/_backend/utils/cloudflare.ts, line 2601:

<comment>Callers can reasonably expect `getPublicLiveUpdateMetricsCF` to return the complete live-update metric contract, but it now returns only breakdowns and omits `success_rate`/`daily`. Renaming it to `getPublicLiveUpdateBreakdownMetricsCF` would keep the exported API aligned with its new responsibility.</comment>

<file context>
@@ -2587,15 +2587,18 @@ export async function getPluginBreakdownCF(c: Context, referenceDate?: Date): Pr
+  daily: Array<{ date: string, success_rate: number }>
+}
+
+export async function getPublicLiveUpdateMetricsCF(c: Context, referenceDate = new Date()): Promise<PublicLiveUpdateBreakdownMetrics> {
   if (!c.env.APP_LOG || !c.env.DEVICE_USAGE || !c.env.DEVICE_INFO || !getEnv(c, 'CF_ANALYTICS_TOKEN') || !getEnv(c, 'CF_ACCOUNT_ANALYTICS_ID'))
     throw new Error('Public live update metric bindings are unavailable')
</file context>
Fix with cubic

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