Skip to content

fix(dashboard): read delivery latency from AE double1 - #2782

Merged
riderx merged 2 commits into
mainfrom
fix/dashboard-delivery-tabs-and-latency
Jul 30, 2026
Merged

fix(dashboard): read delivery latency from AE double1#2782
riderx merged 2 commits into
mainfrom
fix/dashboard-delivery-tabs-and-latency

Conversation

@riderx

@riderx riderx commented Jul 28, 2026

Copy link
Copy Markdown
Member

Summary (AI generated)

  • Read update-delivery duration from Analytics Engine double1 (written by /stats when plugins report timing), not metadata alone.
  • Drop GROUP BY on the timing-events AE query so rows are not collapsed incorrectly.
  • Prefer event.duration_ms when building delivery samples and native-observe samples.
  • Do not cache empty latency responses (avoids sticky “No delivery latency data yet” for ~5 minutes).
  • Clarify empty-state help copy for duration_ms / updater requirement.

UI tab chrome / Notifications beta / email-vs-stats tab work from earlier drafts is out of scope — already shipped in #2786.

Motivation (AI generated)

#2778 wired the CF read path, but prod still showed empty latency because the query never selected double1, used a harmful GROUP BY, and cached zero-sample responses. #2786 fixed dashboard tab UI only; this PR is the remaining data-path fix.

Business Impact (AI generated)

After API worker deploy, orgs whose devices already report download duration can see p50/p75/p95/p99 on the dashboard instead of a permanent empty state.

Test Plan (AI generated)

  • bunx vitest run tests/update-delivery-stats.unit.test.ts tests/native-observe-stats.unit.test.ts tests/analytics-engine-sql.unit.test.ts
  • After API deploy: org with devices reporting duration_ms / AE double1 shows percentiles on Delivery tab
  • Empty orgs still show empty state; refreshing after first real samples is not stuck on a cached empty payload

Generated with AI


Note

Medium Risk
Changes the analytics read path and cache behavior for delivery latency; incorrect duration parsing or caching could show wrong percentiles or delay populated charts, but scope is observability only—not auth or billing.

Overview
Fixes update delivery latency on the dashboard by reading download duration from Analytics Engine double1 (written when /stats reports timing), not only from event metadata.

The timing-events query now selects double1, drops a GROUP BY that collapsed rows, and resolveUpdateDeliveryTimingDurationMs prefers AE duration then metadata (including numeric duration_ms / duration). parseStatsDurationMs is shared across delivery stats and native observe instead of duplicated parsers.

Caching no longer stores responses with zero samples (CF or Postgres), so empty windows from ingest lag are not stuck for the cache TTL. A cloudlog fires when CF returns events but zero delivery samples. Empty-state copy now mentions duration_ms on download_complete and updating @capgo/capacitor-updater.

Reviewed by Cursor Bugbot for commit 8de0d58. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Delivery timing now supports duration data provided as numbers or numeric text.
    • Delivery latency percentiles can be calculated from reported download duration or paired start and completion events.
    • Analytics-based timing data is now used when available, with fallback handling for metadata.
  • Bug Fixes

    • Improved handling of missing or invalid timing data.
    • Empty delivery statistics are no longer cached, improving subsequent reporting accuracy.
    • Updated guidance explains when percentiles become available and recommends updating the updater when timing metadata is missing.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a7bd971a-e49b-4e77-b543-3a53bcd8f62e

📥 Commits

Reviewing files that changed from the base of the PR and between 83d4b45 and 8de0d58.

📒 Files selected for processing (7)
  • messages/en.json
  • supabase/functions/_backend/plugin_runtime/utils/cloudflare.ts
  • supabase/functions/_backend/private/native_observe_stats.ts
  • supabase/functions/_backend/private/update_delivery_stats.ts
  • supabase/functions/_backend/utils/cloudflare.ts
  • tests/native-observe-stats.unit.test.ts
  • tests/update-delivery-stats.unit.test.ts

📝 Walkthrough

Walkthrough

Delivery timing now accepts numeric and string duration metadata, reads Analytics Engine double1 values, and shares resolution logic across delivery statistics and native observe samples. Empty results are no longer cached, and tests and help text reflect the updated timing behavior.

Changes

Delivery timing pipeline

Layer / File(s) Summary
Shared duration parsing and Analytics Engine events
supabase/functions/_backend/utils/cloudflare.ts, supabase/functions/_backend/plugin_runtime/utils/cloudflare.ts
Duration parsing accepts numeric and numeric-string values with shared bounds; Analytics Engine events expose normalized duration_ms values and use metadata fallback resolution.
Delivery statistics and observe-sample integration
supabase/functions/_backend/private/update_delivery_stats.ts, supabase/functions/_backend/private/native_observe_stats.ts
Both pipelines use shared duration resolution; zero-sample results are logged and excluded from Cloudflare and Postgres caches.
Duration behavior validation and messaging
tests/update-delivery-stats.unit.test.ts, tests/native-observe-stats.unit.test.ts, messages/en.json
Tests cover numeric, string, null, metadata, and Analytics Engine durations; delivery latency guidance documents the required timing data.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AnalyticsEngine
  participant CloudflareTimingReader
  participant DeliveryStats
  participant NativeObserveStats
  AnalyticsEngine->>CloudflareTimingReader: return duration_ms and event metadata
  CloudflareTimingReader->>DeliveryStats: provide normalized timing events
  DeliveryStats->>DeliveryStats: resolve duration and build delivery samples
  CloudflareTimingReader->>NativeObserveStats: provide normalized timing events
  NativeObserveStats->>NativeObserveStats: resolve duration and build observe samples
Loading

Possibly related PRs

  • Cap-go/capgo.app#2772: Overlaps with the shared duration parsing and native observe-stats integration.
  • Cap-go/capgo.app#2778: Overlaps with Analytics Engine duration_ms support and delivery-latency reporting.

Suggested reviewers: wcaleniewolny

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Visual diff passed

Visual changes

Generated at 2026-07-28T23:49:21.083Z. Threshold: 0.1% pixel difference.

Route Diff % Status
login 0.000 unchanged
dashboard 6.837 changed
apps 0.053 unchanged
app-overview 1.404 changed
channels 0.012 unchanged
devices 0.110 changed
observe 0.000 unchanged
observe-plugins 0.000 unchanged
api-keys-app-preview 2.211 changed

Commit: 372576647161e903c8f47cc1b789574531a4e3b2
Download the HTML report from workflow artifacts (artifact: visual-diff-report-372576647161e903c8f47cc1b789574531a4e3b2).

Open index.html from the artifact for side-by-side before/after/diff screenshots.

@codspeed-hq

codspeed-hq Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will degrade performance by 43.43%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark
✅ 42 untouched benchmarks
⏩ 2 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
/updates manifest response with metadata 70.2 µs 124.1 µs -43.43%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing fix/dashboard-delivery-tabs-and-latency (8de0d58) with main (36a71e9)

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 force-pushed the fix/dashboard-delivery-tabs-and-latency branch from 9580fdd to 3725766 Compare July 28, 2026 23:44
Prefer Analytics Engine double1 duration, drop the bad timing GROUP BY, and skip caching empty latency windows so prod can surface download timing after deploy.

Co-authored-by: Cursor <cursoragent@cursor.com>
@riderx
riderx force-pushed the fix/dashboard-delivery-tabs-and-latency branch from 3725766 to bae20a9 Compare July 30, 2026 20:50
@riderx riderx changed the title fix(dashboard): tab shell + delivery latency AE double1 fix(dashboard): read delivery latency from AE double1 Jul 30, 2026
@riderx
riderx marked this pull request as ready for review July 30, 2026 21:02
@cursor

cursor Bot commented Jul 30, 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_c867206f-6d41-403d-9cd5-44bcfd391a05)

Deduplicate double1/metadata duration parsing for delivery and native-observe paths to clear Sonar new-code duplication.

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

riderx commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cursor

cursor Bot commented Jul 30, 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_956eaa28-dbec-4fb0-a215-cf2f6b62ef2c)

@sonarqubecloud

Copy link
Copy Markdown

@riderx

riderx commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@riderx
riderx merged commit 49416b6 into main Jul 30, 2026
56 of 77 checks passed
@riderx
riderx deleted the fix/dashboard-delivery-tabs-and-latency branch July 30, 2026 21:39
@riderx

riderx commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. Your recent PR review activity is in the 95th percentile or higher among CodeRabbit users, so adaptive limits apply. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 13 minutes.

@riderx

riderx commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

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