feat(admin): chart app creation build onboarding metrics#2571
Conversation
📝 WalkthroughWalkthroughAdds onboarding provenance fields and daily CLI/manual build metrics, persists and aggregates them, exposes them through admin stats, and renders a new admin dashboard chart. App icon loading now supports RPC rows with missing onboarding fields, and CLI creation retries against older schemas. ChangesApp Build Onboarding Metrics
CI Concurrency Grouping
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant StatsShard
participant MetricsQuery
participant Database
participant AdminTrend
participant Dashboard
StatsShard->>MetricsQuery: compute prior-day onboarding metrics
MetricsQuery->>Database: query apps and 24-hour build requests
Database-->>MetricsQuery: return grouped app/build rows
MetricsQuery-->>StatsShard: return onboarding counters
StatsShard->>Database: update global stats snapshot
Dashboard->>AdminTrend: request global stats trend
AdminTrend-->>Dashboard: return onboarding trend counters
Dashboard->>Dashboard: render onboarding chart series
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
Merging this PR will degrade performance by 38.23%
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing Footnotes
|
e68f3b7 to
4977799
Compare
🧪 Builder onboarding TUI preview — ❌ failed▶ Open the interactive HTML report (zoomable journey tree + cast playback) Commit: 202e524 · Job summary with the result table |
4977799 to
ab04a7f
Compare
ab04a7f to
aad7d3b
Compare
aad7d3b to
202e524
Compare
202e524 to
b504255
Compare
b504255 to
09f48a1
Compare
There was a problem hiding this comment.
Stale comment
Risk: medium. Cursor Bugbot remained pending after the 8-minute polling window, so automated review is incomplete and I am not approving. Human review is needed for the migration, backend trigger, and admin dashboard changes.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/types/supabase.types.ts (1)
321-332: 🗄️ Data Integrity & Integration | 🟡 MinorUpdate TypeScript RPC return types to reflect actual column availability.
The new
created_from_onboardingandonboarding_completed_atcolumns are missing from the TypeScript type definitions for both RPC functions:
get_accessible_apps_for_apikey_v2(line 3596): Returns fullappsrow at SQL level but TypeScript types omit the new fields, causing type-SQL mismatch.get_org_apps_with_last_upload(line 3824): Intentionally excludes these fields (per SQL comment: "stable apps list contract"), so TypeScript correctly omits them—but this is by design.The consumer code in
src/pages/apps.vue:42-43works around this with fallback logic ('created_from_onboarding' in app), but relying on runtime field presence is fragile. Regenerate the TypeScript types to match the SQL schema.🤖 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 `@src/types/supabase.types.ts` around lines 321 - 332, The TypeScript type definitions in the Supabase types file for the RPC functions `get_accessible_apps_for_apikey_v2` and `get_org_apps_with_last_upload` are out of sync with the actual SQL schema. The `get_accessible_apps_for_apikey_v2` function should include the `created_from_onboarding` and `onboarding_completed_at` fields since it returns the full apps row at the SQL level, while `get_org_apps_with_last_upload` should continue to exclude these fields as per its design contract for a stable API. Regenerate the TypeScript type definitions from the Supabase schema to ensure they accurately reflect what each RPC function returns, eliminating the need for runtime field presence checks in consumer code like `src/pages/apps.vue`.
🤖 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.
Outside diff comments:
In `@src/types/supabase.types.ts`:
- Around line 321-332: The TypeScript type definitions in the Supabase types
file for the RPC functions `get_accessible_apps_for_apikey_v2` and
`get_org_apps_with_last_upload` are out of sync with the actual SQL schema. The
`get_accessible_apps_for_apikey_v2` function should include the
`created_from_onboarding` and `onboarding_completed_at` fields since it returns
the full apps row at the SQL level, while `get_org_apps_with_last_upload` should
continue to exclude these fields as per its design contract for a stable API.
Regenerate the TypeScript type definitions from the Supabase schema to ensure
they accurately reflect what each RPC function returns, eliminating the need for
runtime field presence checks in consumer code like `src/pages/apps.vue`.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: f35cf478-0df7-4267-872c-cdec0940988a
📒 Files selected for processing (15)
cli/src/types/supabase.types.tsdocs/pr-assets/admin-app-build-onboarding-chart.webpmessages/en.jsonread_replicate/schema_replicate.sqlsrc/pages/admin/dashboard/index.vuesrc/pages/apps.vuesrc/types/supabase.types.tssupabase/functions/_backend/public/app/post.tssupabase/functions/_backend/triggers/logsnag_insights.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/supabase.types.tssupabase/migrations/20260623144909_admin_app_build_onboarding_metrics.sqltests/admin-stats.test.tstests/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)
There was a problem hiding this comment.
Stale comment
Risk: medium. Cursor Bugbot is still pending after the 8-minute polling window and no Bugbot review comment was posted, so I am not approving without that automated signal. Human review is needed for the migration, backend metrics pipeline, and admin dashboard changes; WcaleNieWolny is already requested and I also requested Dalanir.
Sent by Cursor Approval Agent: Pull Request Approver
09f48a1 to
22c3dc0
Compare
There was a problem hiding this comment.
Stale comment
Risk: medium. Cursor Bugbot finished with a skipped status and no Bugbot review comment was posted, so I am not approving without that automated signal. Human review is still needed for the migration, backend metrics pipeline, and admin dashboard changes; WcaleNieWolny and Dalanir are already requested.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Stale comment
Risk: medium. Cursor Bugbot finished with a skipped check and reported 2 unresolved findings (including one high-severity metrics timing issue), so I am not approving. WcaleNieWolny and Dalanir are already requested for human review of the migration, backend metrics pipeline, and admin dashboard changes.
Sent by Cursor Approval Agent: Pull Request Approver
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 1351-1392: The snapshot timing issue occurs because
getAppBuildOnboardingMetrics is being called too early in the day (01:01 UTC) to
capture the full 24-hour observation windows for apps created near the end of
the previous day. Find where getAppBuildOnboardingMetrics is invoked in the
snapshot recording workflow and delay the execution until after 23:59 UTC to
ensure all apps created the previous day have completed their full 24-hour build
observation window before the metric is recorded.
In `@supabase/migrations/20260623144909_admin_app_build_onboarding_metrics.sql`:
- Around line 48-52: The two CREATE INDEX statements for idx_apps_created_at and
idx_build_requests_app_created_at are missing the CONCURRENTLY keyword, which
will cause write locks on these tables during the migration. Add the
CONCURRENTLY keyword to both CREATE INDEX IF NOT EXISTS statements so that the
indexes are built without blocking concurrent write operations on the
public.apps and public.build_requests tables.
🪄 Autofix (Beta)
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: 037135c6-e2bc-4a1f-87b2-7c4102af84f8
📒 Files selected for processing (15)
cli/src/types/supabase.types.tsdocs/pr-assets/admin-app-build-onboarding-chart.webpmessages/en.jsonread_replicate/schema_replicate.sqlsrc/pages/admin/dashboard/index.vuesrc/pages/apps.vuesrc/types/supabase.types.tssupabase/functions/_backend/public/app/post.tssupabase/functions/_backend/triggers/logsnag_insights.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/supabase.types.tssupabase/migrations/20260623144909_admin_app_build_onboarding_metrics.sqltests/admin-stats.test.tstests/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)
| CREATE INDEX IF NOT EXISTS idx_apps_created_at | ||
| ON public.apps (created_at); | ||
|
|
||
| CREATE INDEX IF NOT EXISTS idx_build_requests_app_created_at | ||
| ON public.build_requests (app_id, created_at); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift
Use concurrent index creation to avoid deploy-time write blocking.
Line 48 and Line 51 create indexes without CONCURRENTLY. On large tables, this can block writes for the migration duration and degrade API availability. Move these to a dedicated migration that builds indexes concurrently.
Suggested change
-CREATE INDEX IF NOT EXISTS idx_apps_created_at
-ON public.apps (created_at);
-
-CREATE INDEX IF NOT EXISTS idx_build_requests_app_created_at
-ON public.build_requests (app_id, created_at);
+-- Run in a dedicated migration that supports non-transactional statements
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_apps_created_at
+ON public.apps (created_at);
+
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_build_requests_app_created_at
+ON public.build_requests (app_id, created_at);🤖 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/20260623144909_admin_app_build_onboarding_metrics.sql`
around lines 48 - 52, The two CREATE INDEX statements for idx_apps_created_at
and idx_build_requests_app_created_at are missing the CONCURRENTLY keyword,
which will cause write locks on these tables during the migration. Add the
CONCURRENTLY keyword to both CREATE INDEX IF NOT EXISTS statements so that the
indexes are built without blocking concurrent write operations on the
public.apps and public.build_requests tables.
Bugbot couldn't run - usage limit reachedBugbot 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_011648b8-020c-4946-bf39-935dad061217) |
Bugbot couldn't run - usage limit reachedBugbot 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_ab2b0d5d-9fda-47e8-ae01-fdcd3c0ae240) |
There was a problem hiding this comment.
Stale comment
Risk: medium. Cursor Bugbot finished with a skipped check on the latest sync, and the prior Bugbot review still has 4 unresolved findings (including high severity), so I am not approving. WcaleNieWolny and Dalanir are already requested for human review.
Sent by Cursor Approval Agent: Pull Request Approver
There was a problem hiding this comment.
Stale comment
Risk: medium. Cursor Bugbot finished with a skipped check on the latest sync (usage limit reached), and the prior Bugbot review still has unresolved findings, so I am not approving. WcaleNieWolny and Dalanir are already requested for human review.
Sent by Cursor Approval Agent: Pull Request Approver External
Bugbot couldn't run - usage limit reachedBugbot 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_cec601f7-7abf-4153-bfe2-bf0427d2fb23) |
There was a problem hiding this comment.
Stale comment
Risk: medium. Cursor Bugbot finished with a skipped check on the latest sync (usage limit reached), and the prior Bugbot review still has 5 unresolved findings, so I am not approving. WcaleNieWolny and Dalanir are already requested for human review.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 @.github/workflows/tests.yml:
- Line 4: Update the workflow concurrency group expression to use
github.event.pull_request.number for pull_request events, while retaining the
SHA-based key for workflow_call and the existing branch/ref fallback for other
events, so unrelated PR runs cannot cancel each other.
In `@messages/en.json`:
- Line 1210: Remove the duplicate "events" key from messages/en.json, preferably
the later definition, while retaining the established earlier entry so the JSON
contains only one events property.
🪄 Autofix (Beta)
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: 0a532249-e4c4-4ef5-9b9b-61e16ebd2a5b
📒 Files selected for processing (7)
.github/workflows/tests.ymlcli/src/app/add.tscli/src/types/supabase.types.tsdocs/pr-assets/admin-app-build-onboarding-chart.webpmessages/en.jsonread_replicate/schema_replicate.catalog.jsonread_replicate/schema_replicate.sql
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
Cap-go/capacitor-updater(manual)
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 2
🤖 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 @.github/workflows/tests.yml:
- Line 4: Update the workflow concurrency group expression to use
github.event.pull_request.number for pull_request events, while retaining the
SHA-based key for workflow_call and the existing branch/ref fallback for other
events, so unrelated PR runs cannot cancel each other.
In `@messages/en.json`:
- Line 1210: Remove the duplicate "events" key from messages/en.json, preferably
the later definition, while retaining the established earlier entry so the JSON
contains only one events property.
🪄 Autofix (Beta)
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: 0a532249-e4c4-4ef5-9b9b-61e16ebd2a5b
📒 Files selected for processing (7)
.github/workflows/tests.ymlcli/src/app/add.tscli/src/types/supabase.types.tsdocs/pr-assets/admin-app-build-onboarding-chart.webpmessages/en.jsonread_replicate/schema_replicate.catalog.jsonread_replicate/schema_replicate.sql
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
Cap-go/capacitor-updater(manual)
🛑 Comments failed to post (2)
.github/workflows/tests.yml (1)
4-4: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail echo '--- .github/workflows/tests.yml ---' nl -ba .github/workflows/tests.yml | sed -n '1,80p' echo echo '--- other workflow concurrency keys ---' rg -n "concurrency:|group:" .github/workflows -A4 -B2 || true echo echo '--- workflow triggers in tests.yml ---' sed -n '1,80p' .github/workflows/tests.yml | rg -n "on:|workflow_call|pull_request|push|schedule|workflow_dispatch|concurrency|cancel-in-progress" -n -A3 -B3 || trueRepository: Cap-go/capgo
Length of output: 226
🏁 Script executed:
#!/bin/bash set -euo pipefail nl -ba .github/workflows/tests.yml | sed -n '1,120p'Repository: Cap-go/capgo
Length of output: 190
🏁 Script executed:
#!/bin/bash set -euo pipefail echo '--- .github/workflows/tests.yml ---' sed -n '1,120p' .github/workflows/tests.yml echo echo '--- workflow concurrency references ---' rg -n "concurrency:|group:|cancel-in-progress:|workflow_call|pull_request|push" .github/workflows -A4 -B2 || trueRepository: Cap-go/capgo
Length of output: 33081
Keep PR runs isolated in the concurrency key.
.github/workflows/tests.yml:4uses only the branch name forpull_requestandpushruns, so two PRs from different forks with the same branch name—or a push and its PR check on the same branch—can cancel each other whencancel-in-progress: trueis set. Usegithub.event.pull_request.numberfor PR events and keep the SHA-based key forworkflow_call.🤖 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 @.github/workflows/tests.yml at line 4, Update the workflow concurrency group expression to use github.event.pull_request.number for pull_request events, while retaining the SHA-based key for workflow_call and the existing branch/ref fallback for other events, so unrelated PR runs cannot cancel each other.messages/en.json (1)
1210-1210: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Remove the duplicate
eventskey.
"events"is defined at Line 1210 and again at Line 2492. Biome reports this duplicate key; keep only one definition so linting and JSON parsing remain deterministic.Proposed fix
- "events": "Events",Remove either duplicate definition, preferably the later one if the earlier key is already established.
Also applies to: 2492-2492
🧰 Tools
🪛 Biome (2.5.1)
[error] 1210-1210: The key events was already declared.
(lint/suspicious/noDuplicateObjectKeys)
🤖 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 `@messages/en.json` at line 1210, Remove the duplicate "events" key from messages/en.json, preferably the later definition, while retaining the established earlier entry so the JSON contains only one events property.Source: Linters/SAST tools
…-onboarding-metrics
Bugbot couldn't run - usage limit reachedBugbot 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_8ab8fcf4-bd56-4948-af2a-66da55e455f9) |
There was a problem hiding this comment.
Stale comment
Risk: medium. Cursor Bugbot finished with a skipped check on the latest sync (usage limit reached) and did not post a fresh review for the current commit, so I am not approving. WcaleNieWolny and Dalanir are already requested for human review.
Sent by Cursor Approval Agent: Pull Request Approver
Bugbot couldn't run - usage limit reachedBugbot 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_00fc01d3-faf5-42fc-a20e-dcb5d611dddb) |
|





Summary
global_statscounters for apps created, first-day CLI onboarding builds, and first-day manual builds.manualorcli_onboardingand normalize missing/unknown sources server-side.Screenshot
Validation
bun lintbun lint:backendbun typecheckbun run cli:checkbun test tests/admin-stats.test.tsbun test ./test/prescan/request-gate.test.tsfromcli/bun run supabase:db:resetbunx supabase db lint --localfrom.context/supabase-worktrees/c85d6572(exits 0 with existing warnings)docs/pr-assets/admin-app-build-onboarding-chart.webpNote
Medium Risk
Touches app creation paths, a DB migration/trigger, and daily global-stats aggregation; incorrect cohort logic would skew admin metrics but not core auth or billing.
Overview
Adds onboarding provenance on
apps(created_from_onboarding,onboarding_completed_atvia trigger whenneed_onboardingflips off) plus dailyglobal_statscounters for apps created and first-day build activity (>2 succeeded builds in 24h, split CLI-onboarding vs manual).Ingestion: CLI
addsetscreated_from_onboardingfor onboarding creates (with schema-missing fallback); public app create mirrorsneed_onboardinginto that flag. Aggregation:logsnag_insightswrites cohort metrics to the prior UTC day once the 24h window can complete; admin trend API exposes them withapp_build_onboarding_finalizedwhen the next day’s core shard exists.UI: New admin multi-line chart and i18n labels; apps list normalizes onboarding fields from RPC rows. Migration redefines
get_org_apps_with_last_uploadwith an explicit column list (noapps.*). CI concurrency usesgithub.head_reffor PRs. Tests cover summarization, trend fields, and admin stats.Reviewed by Cursor Bugbot for commit 30eae79. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
New Features
Bug Fixes
Tests