Skip to content

feat(admin): daily history of apps with preview QR enabled - #2937

Merged
riderx merged 1 commit into
mainfrom
cursor/apps-preview-qr-history-bbd5
Aug 8, 2026
Merged

feat(admin): daily history of apps with preview QR enabled#2937
riderx merged 1 commit into
mainfrom
cursor/apps-preview-qr-history-bbd5

Conversation

@riderx

@riderx riderx commented Aug 8, 2026

Copy link
Copy Markdown
Member

Summary (AI generated)

  • Add global_stats.apps_with_preview daily snapshot of apps with allow_preview = true
  • Fill it in the core logsnag_insights global stats shard
  • Expose the metric via global_stats_trend / getAdminGlobalStatsTrend
  • Chart evolution over time on the admin Users dashboard

Motivation (AI generated)

Preview QR adoption needs a historical view. A live count only shows today. Daily snapshots in global_stats match existing admin KPI patterns and keep the dashboard off hot-path scans.

Business Impact (AI generated)

Makes preview QR rollout measurable day by day, so product can see adoption trend without ad-hoc SQL.

Test Plan (AI generated)

  • Unit test asserts core shard counts allow_preview apps into apps_with_preview
  • Apply migration / reset DB and confirm global_stats.apps_with_preview exists
  • After a core shard run (or manual insert), confirm admin Users chart “Apps with Preview QR Enabled” plots the series
  • Confirm past days stay at default 0 until snapshots exist (no fake backfill)

Generated with AI

Open in Web Open in Cursor 

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added an admin dashboard chart showing trends for apps with Preview QR enabled.
    • Added English labels for Preview QR metrics and trend data.
    • Global statistics now include the number of apps with Preview QR enabled.
  • Bug Fixes

    • Improved metric snapshots to count Preview-enabled apps using the correct creation-time boundary.
  • Tests

    • Added coverage verifying Preview QR statistics are captured correctly.

Snapshot allow_preview app counts into global_stats each day and chart
the trend on the admin users dashboard.

Co-authored-by: Martin DONADIEU <martindonadieu@gmail.com>
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The change adds an apps_with_preview global statistic. It stores the daily count, exposes it in trend data, and displays it on the admin Users dashboard with localization and unit coverage.

Changes

Preview global statistics

Layer / File(s) Summary
Global statistics schema contracts
supabase/migrations/..., */types/supabase.types.ts
Adds the non-null global_stats.apps_with_preview column and updates database types for rows, inserts, and updates.
Snapshot computation and trend mapping
supabase/functions/_backend/triggers/logsnag_insights.ts, supabase/functions/_backend/*/utils/pg.ts
Counts Preview-enabled apps before snapshotEnd, stores and logs the metric, and maps it into admin trend results with zero fallbacks.
Dashboard chart and validation
src/pages/admin/dashboard/users.vue, messages/en.json, tests/logsnag-insights-revenue.unit.test.ts
Adds the Preview app trend series and chart, English labels, and coverage for filtering and shard output.

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

Sequence Diagram(s)

sequenceDiagram
  participant LogsnagInsights
  participant AppsDatabase
  participant GlobalStats
  participant AdminDashboard
  LogsnagInsights->>AppsDatabase: Count Preview-enabled apps before snapshotEnd
  AppsDatabase-->>LogsnagInsights: Return apps_with_preview count
  LogsnagInsights->>GlobalStats: Persist daily metric
  AdminDashboard->>GlobalStats: Request global statistics trend
  GlobalStats-->>AdminDashboard: Return apps_with_preview trend
  AdminDashboard-->>AdminDashboard: Render Preview app chart
Loading

Possibly related PRs

Suggested labels: codex

Suggested reviewers: dalanir, cursor

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding daily history for apps with Preview QR enabled.
Description check ✅ Passed The description covers the change, motivation, business impact, and test plan, while identifying remaining validation steps.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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

@codspeed-hq

codspeed-hq Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 43 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing cursor/apps-preview-qr-history-bbd5 (0b587b1) with main (e82dd01)

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

sonarqubecloud Bot commented Aug 8, 2026

Copy link
Copy Markdown

@riderx
riderx marked this pull request as ready for review August 8, 2026 17:08
@cursor

cursor Bot commented Aug 8, 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_a7be304d-a89c-4cba-bffc-080585fecc3f)

@coderabbitai coderabbitai Bot added the codex label Aug 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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.

Inline comments:
In `@supabase/functions/_backend/triggers/logsnag_insights.ts`:
- Around line 1507-1509: Update the countAppsWithPreview error handler to keep
logging the database error, then rethrow it instead of returning 0. Preserve the
successful count path so shard failure handling can detect the failure and retry
the snapshot.

In `@supabase/migrations/20260808071749_apps_with_preview_global_stats.sql`:
- Around line 1-2: Update the migration adding apps_with_preview so existing
global_stats rows are not populated with misleading zero values. Backfill
historical values from a source containing the recorded allow_preview state, or
constrain the trend to begin at the first valid snapshot; do not derive
historical values from the current apps.allow_preview state.
- Line 5: Shorten or split the SQL comment attached to the preview-apps
statistic so each line is no longer than 80 characters, while preserving its
meaning about apps with allow_preview enabled at snapshot day end.

In `@tests/logsnag-insights-revenue.unit.test.ts`:
- Around line 683-694: Replace the source-string assertions in the “snapshots
apps with preview QR enabled” test with a behavioral test that executes the
relevant stats flow using mocked database clients or an existing database
fixture. Seed records covering preview-enabled apps before and at the snapshot
boundary, verify countAppsWithPreview returns only records before snapshotEnd,
and assert runCoreGlobalStatsShard passes that value as apps_with_preview to
updateGlobalStatsSnapshot.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7f87c1a3-461d-4d17-8836-d2bad93eaeaf

📥 Commits

Reviewing files that changed from the base of the PR and between e82dd01 and 0b587b1.

📒 Files selected for processing (11)
  • cli/src/types/supabase.types.ts
  • messages/en.json
  • src/pages/admin/dashboard/users.vue
  • src/types/supabase.types.ts
  • supabase/functions/_backend/plugin_runtime/utils/pg.ts
  • supabase/functions/_backend/plugin_runtime/utils/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/20260808071749_apps_with_preview_global_stats.sql
  • tests/logsnag-insights-revenue.unit.test.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Cap-go/capacitor-updater (manual)

Comment on lines +1507 to +1509
catch (error) {
cloudlogErr({ requestId: c.get('requestId'), message: 'countAppsWithPreview error', error })
return 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Propagate count failures instead of recording zero.

Lines [1507-1509] convert every database error into a valid-looking 0. The core shard can then persist that value as the snapshot, making a failed query indistinguishable from zero preview-enabled apps. Log the error and rethrow it so shard failure handling can retry the snapshot.

Suggested error propagation
   catch (error) {
     cloudlogErr({ requestId: c.get('requestId'), message: 'countAppsWithPreview error', error })
-    return 0
+    throw error
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
catch (error) {
cloudlogErr({ requestId: c.get('requestId'), message: 'countAppsWithPreview error', error })
return 0
catch (error) {
cloudlogErr({ requestId: c.get('requestId'), message: 'countAppsWithPreview error', error })
throw error
🤖 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 `@supabase/functions/_backend/triggers/logsnag_insights.ts` around lines 1507 -
1509, Update the countAppsWithPreview error handler to keep logging the database
error, then rethrow it instead of returning 0. Preserve the successful count
path so shard failure handling can detect the failure and retry the snapshot.

Comment on lines +1 to +2
ALTER TABLE public.global_stats
ADD COLUMN IF NOT EXISTS apps_with_preview bigint NOT NULL DEFAULT 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Prevent false historical values.

DEFAULT 0 writes 0 into every existing global_stats row. The trend will report false zeros for dates before August 8, 2026, unless downstream queries exclude those rows.

Backfill from a source that records historical allow_preview state, or start the trend at the first real snapshot. Do not derive historical values from the current apps.allow_preview state.

🤖 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 `@supabase/migrations/20260808071749_apps_with_preview_global_stats.sql` around
lines 1 - 2, Update the migration adding apps_with_preview so existing
global_stats rows are not populated with misleading zero values. Backfill
historical values from a source containing the recorded allow_preview state, or
constrain the trend to begin at the first valid snapshot; do not derive
historical values from the current apps.allow_preview state.

ADD COLUMN IF NOT EXISTS apps_with_preview bigint NOT NULL DEFAULT 0;

COMMENT ON COLUMN public.global_stats.apps_with_preview
IS 'Number of apps with preview QR enabled (allow_preview = true) at snapshot day end.';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the SQL comment line length.

SQLFluff reports that Line 5 is 90 characters, exceeding the 80-character limit. Shorten or split the comment without changing its meaning.

Proposed fix
-  IS 'Number of apps with preview QR enabled (allow_preview = true) at snapshot day end.';
+  IS 'Apps with preview QR enabled at snapshot day end (allow_preview = true).';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
IS 'Number of apps with preview QR enabled (allow_preview = true) at snapshot day end.';
IS 'Apps with preview QR enabled at snapshot day end (allow_preview = true).';
🧰 Tools
🪛 SQLFluff (4.2.2)

[error] 5-5: Line is too long (90 > 80).

(LT05)

🤖 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 `@supabase/migrations/20260808071749_apps_with_preview_global_stats.sql` at
line 5, Shorten or split the SQL comment attached to the preview-apps statistic
so each line is no longer than 80 characters, while preserving its meaning about
apps with allow_preview enabled at snapshot day end.

Source: Linters/SAST tools

Comment on lines +683 to +694

it.concurrent('snapshots apps with preview QR enabled in the core global stats shard', () => {
const source = readFileSync(new URL('../supabase/functions/_backend/triggers/logsnag_insights.ts', import.meta.url), 'utf8')
const countFn = source.match(/async function countAppsWithPreview[\s\S]*?async function getTrialExtensionStats/)?.[0] ?? ''
const coreShard = source.match(/async function runCoreGlobalStatsShard[\s\S]*?async function getRegistersToday/)?.[0] ?? ''

expect(countFn).toContain('apps.allow_preview = true')
expect(countFn).toContain('apps.created_at <')
expect(countFn).toContain('snapshotEnd')
expect(coreShard).toContain('countAppsWithPreview(c, window.prevDayEnd)')
expect(coreShard).toContain('apps_with_preview,')
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔵 Trivial | 🏗️ Heavy lift

Test the metric behavior instead of matching source text.

Lines [685-694] only inspect implementation strings. They do not execute countAppsWithPreview, verify the snapshotEnd boundary with data, or confirm the value passed to updateGlobalStatsSnapshot. A broken query that always returns zero can still pass this test. Add a behavioral test with mocked database clients or an existing database-backed fixture.

🤖 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 `@tests/logsnag-insights-revenue.unit.test.ts` around lines 683 - 694, Replace
the source-string assertions in the “snapshots apps with preview QR enabled”
test with a behavioral test that executes the relevant stats flow using mocked
database clients or an existing database fixture. Seed records covering
preview-enabled apps before and at the snapshot boundary, verify
countAppsWithPreview returns only records before snapshotEnd, and assert
runCoreGlobalStatsShard passes that value as apps_with_preview to
updateGlobalStatsSnapshot.

@riderx
riderx merged commit 034dd27 into main Aug 8, 2026
68 of 76 checks passed
@riderx
riderx deleted the cursor/apps-preview-qr-history-bbd5 branch August 8, 2026 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants