refactor(api): migrate functions.invoke to Cloudflare API - #2785
Conversation
Capgo cloud traffic already runs on Cloudflare Workers; only `triggers` must stay on Supabase for pg_net queue_consumer. Keep full deploy for self-hosting. Co-authored-by: Cursor <cursoragent@cursor.com>
Address review feedback: show allowlisted Capgo Cloud deploy commands and cover empty/multi-target allowlist deploy arg cases. Co-authored-by: Cursor <cursoragent@cursor.com>
supabase.functions.invoke always uses SUPABASE_URL, so console/CLI still need private, apikey, app, bundle, channel, files, organization, statistics, and webhooks published alongside triggers. Co-authored-by: Cursor <cursoragent@cursor.com>
Stop Capgo cloud console traffic on sb.capgo.app edge functions by calling api.capgo.app instead. Migrate CLI the same way while keeping bundle/channel/files/private published until 2026-10-28 for older CLIs. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 3 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (18)
📝 WalkthroughWalkthroughThe PR adds allowlisted Supabase function deployment with cleanup, introduces cloud/self-hosted Capgo API routing for the CLI, and migrates frontend Supabase Edge Function calls to shared Capgo API services with updated tests. ChangesCapgo API and deployment routing
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Frontend
participant invokeCapgoApi
participant CapgoApiOrSupabase
Frontend->>invokeCapgoApi: send endpoint, method, body, and access mode
invokeCapgoApi->>CapgoApiOrSupabase: route to Capgo cloud or Supabase Functions
CapgoApiOrSupabase-->>invokeCapgoApi: return JSON, text, or error response
invokeCapgoApi-->>Frontend: return standardized data and error
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
Comment |
Merging this PR will not alter performance
Comparing Footnotes
|
Default invoke helpers to any like supabase.functions.invoke and tighten the few call sites that still need explicit shapes for typecheck. Co-authored-by: Cursor <cursoragent@cursor.com>
log-as and apikeys unit tests still stubbed supabase.functions.invoke after the Cloudflare helper migration; point them at invokeCapgoApi instead. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@coderabbitai review |
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_5b4e8f49-4017-49fb-8cfc-975b08519925) |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
All reported issues were addressed across 39 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Keep unread error bodies for FunctionsHttpError, support anonymous invite bootstrap, fall back to /functions/v1 for self-host consoles, fix CLI auth and Capgo-managed --supa-host routing, and make Capgo cloud deploy fail closed plus delete non-allowlisted functions. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Stale comment
Risk: high. Left a non-blocking comment — Cursor Bugbot completed as skipped, so it is not a clean approval signal, and this PR changes console/CLI API routing plus Capgo cloud function publish allowlists (auth, billing, and deploy surface). Assigning reviewers for human review; no approval from this run.
Sent by Cursor Approval Agent: Pull Request Approver
There was a problem hiding this comment.
Stale comment
Risk: high. Left a non-blocking comment — Cursor Bugbot did not complete successfully (skipped due to usage limit), and this PR is above the low-risk approval threshold given broad console/CLI API routing and deploy-surface changes. Assigned reviewers for human review.
Sent by Cursor Approval Agent: Pull Request Approver External
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/pages/app/[app].channel.[channel].devices.vue (1)
119-176: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winRoute
setChannelDeviceOverridethroughinvokeCapgoApi.Self-host/local consoles route API calls through Supabase
/functions/v1, but this flow still postschannel_devicedirectly toVITE_API_HOST, bypassing that fallback and potentially sending the override request to Capgo Cloud. Migrate this call toinvokeCapgoApiand handle its returned 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 `@src/pages/app/`[app].channel.[channel].devices.vue around lines 119 - 176, Update setChannelDeviceOverride to call invokeCapgoApi for private/channel_device instead of fetch against defaultApiHost, preserving the existing app, channel, and device request fields. Handle the returned error in customDeviceOverwritePart5 through the existing overwrite-error path, and remove the direct session/JWT and HTTP response handling.
🤖 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 `@cli/src/utils.ts`:
- Around line 792-862: Update invokeCapgoCliApi to reuse the result of
getRemoteConfig(true) across calls during the CLI process, while preserving
explicit supaHost/supaAnon behavior and avoiding stale configuration beyond that
process. Review the non-functions/v1 Authorization construction in
invokeCapgoCliApi against the Cloudflare API contract; use the required Bearer
format if the API validates Authorization, otherwise retain raw-key behavior
only when capgkey is intentionally the sole credential and ensure the
implementation reflects that contract.
- Around line 748-757: Validate the --supa-host value centrally before routing
or invoking the API, using isCapgoManagedSupabaseHost and the existing
host-normalization flow where appropriate. Reject malformed or unsupported hosts
with a clear CLI-facing error that states the required URL format, and ensure
this validation occurs inside invokeCapgoCliApi()’s error-handling path so raw
“Invalid URL” TypeErrors do not escape.
In `@package.json`:
- Around line 187-188: Make Supabase stale-function cleanup fail closed: in
package.json lines 187-188, remove unconditional success masking from
deploy:supabase:prod and deploy:supabase:preprod, ignoring deletion errors only
when the function is confirmed missing; in
.github/workflows/build_and_deploy.yml lines 97-109, ensure cleanup failures
propagate and fail the workflow rather than being masked; in README.md lines
467-470, document the full cleanup-aware deployment procedure or explicitly
state that the alternate command does not remove stale functions.
In `@README.md`:
- Around line 80-83: Correct the console/CLI routing description in the README
paragraph: limit SUPABASE_URL routing to self-hosted deployments and legacy CLI
compatibility through October 28, 2026. State that the migrated Capgo Cloud
console uses VITE_API_HOST and the new CLI uses Capgo API hosts, while
preserving the existing Supabase function and pg_net context.
In `@src/components/dashboard/AppOnboardingFlow.vue`:
- Around line 644-648: Update the organization-creation error handling in the
unified onboarding flow around the `if (error || !data?.id)` block to read the
duplicate-name code from the HTTP error body by parsing the `FunctionsHttpError`
response in `error.context` before checking for `23505`. Use the parsed body
code for the `org-with-this-name-exists` toast, while preserving the generic
`cannot-create-org` fallback.
In `@src/services/apikeys.ts`:
- Line 68: Update each invokeCapgoApi call in src/services/apikeys.ts:68-68 and
124-124, src/services/chartDataService.ts:39-39, src/utils/invites.ts:44-44, and
src/utils/onboardingAppCreateHelpers.ts:124-124 to pass the caller-supplied
Supabase client/context, preserving injected client, session, and configuration
behavior instead of resolving the global client.
In `@src/services/capgoApi.ts`:
- Line 4: Update the method type declaration to use the repository’s accepted
single-quote style for all HTTP method literals, without changing the allowed
values or optional property behavior.
In `@src/services/emailOtp.ts`:
- Around line 52-54: Update the invokeCapgoApi call in the email OTP
verification flow to pass allowAnonymous: true, preserving unauthenticated
access while keeping the existing token sanitization and
private/verify_email_otp endpoint unchanged.
In `@tests/apikeys-service.unit.test.ts`:
- Around line 32-40: Remove the concurrent modifier from the “creates a member
key with only the selected app bindings” test so it runs as a standard
sequential test, preserving the shared hoisted mocks and beforeEach resets.
In `@tests/supabase-cloud-functions.unit.test.ts`:
- Around line 39-41: Extend the existing buildCapgoCloudSupabaseDeployArgs test
coverage to assert that passing an empty array throws, preserving the
fail-closed guard while retaining the explicit-list expectation.
---
Outside diff comments:
In `@src/pages/app/`[app].channel.[channel].devices.vue:
- Around line 119-176: Update setChannelDeviceOverride to call invokeCapgoApi
for private/channel_device instead of fetch against defaultApiHost, preserving
the existing app, channel, and device request fields. Handle the returned error
in customDeviceOverwritePart5 through the existing overwrite-error path, and
remove the direct session/JWT and HTTP response handling.
🪄 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: 24a10173-2a16-4ac1-8f48-d066b11fe8a1
📒 Files selected for processing (39)
.github/workflows/build_and_deploy.ymlREADME.mdcli/src/bundle/upload.tscli/src/channel/delete.tscli/src/channel/set.tscli/src/utils.tspackage.jsonscripts/supabase-cloud-functions.tssrc/components/dashboard/AppAccess.vuesrc/components/dashboard/AppOnboardingFlow.vuesrc/components/dashboard/AppSetting.vuesrc/components/dashboard/InviteTeammateModal.vuesrc/components/dashboard/StepsApp.vuesrc/components/dashboard/Usage.vuesrc/components/permissions/ChannelAccessPanel.vuesrc/components/tables/AccessTable.vuesrc/pages/ApiKeys.vuesrc/pages/app/[app].channel.[channel].devices.vuesrc/pages/invitation.vuesrc/pages/onboarding/organization.vuesrc/pages/settings/account/ChangePassword.vuesrc/pages/settings/account/ManageTwoFactor.vuesrc/pages/settings/organization/Members.vuesrc/pages/settings/organization/Plans.vuesrc/pages/settings/organization/Security.vuesrc/pages/settings/organization/index.vuesrc/services/apikeys.tssrc/services/capgoApi.tssrc/services/chartDataService.tssrc/services/emailOtp.tssrc/services/logAs.tssrc/services/stripe.tssrc/services/supabase.tssrc/stores/webhooks.tssrc/utils/invites.tssrc/utils/onboardingAppCreateHelpers.tstests/apikeys-service.unit.test.tstests/log-as-service.unit.test.tstests/supabase-cloud-functions.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: high. Left a non-blocking comment — Cursor Bugbot completed as skipped on this sync, and this PR exceeds the low-risk approval threshold (console/CLI API routing plus Capgo cloud deploy allowlist changes). Reviewers are already assigned; no approval from this run.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Stale comment
Risk: high. Left a non-blocking comment — Cursor Bugbot did not complete successfully on this commit (skipped/neutral), and unresolved Bugbot findings remain on this broad console/CLI API-routing and deploy-surface change. Reviewers are already assigned; no additional reviewers added.
Sent by Cursor Approval Agent: Pull Request Approver
There was a problem hiding this comment.
1 issue found across 10 files (changes from recent commits).
Confidence score: 2/5
- In
src/services/capgoApi.ts, the host check is too permissive (includes-style), so self-hosted domains that merely contain a managed hostname can be misrouted toVITE_API_HOST, causing bearer tokens to be sent to the wrong backend; this is a concrete auth/security regression risk for affected tenants — compare parsed hostnames for exact equality and keep non-managed hosts on/functions/v1.
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="src/services/capgoApi.ts">
<violation number="1" location="src/services/capgoApi.ts:19">
P1: Self-hosts whose domain merely contains a managed hostname are routed to `VITE_API_HOST` and their session bearer token is sent there instead of `/functions/v1`. Match parsed hostnames exactly so only Capgo-managed Supabase origins use the Cloudflare path.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
Mount role_bindings and website_preview on the Cloudflare API worker, match Capgo-managed Supabase hosts by exact hostname, fix app stats query URLs, allow anonymous OTP verify, parse org duplicate errors from HTTP bodies, and make Capgo cloud function cleanup fail closed. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Stale comment
Risk: high. Left a non-blocking comment — Cursor Bugbot did not complete successfully (skipped) and still has an unresolved finding on this broad console/CLI API-routing and Capgo cloud deploy-surface change. Reviewers are already assigned; no approval from this run.
Sent by Cursor Approval Agent: Pull Request Approver
There was a problem hiding this comment.
Stale comment
Risk: high. Left a non-blocking comment — Cursor Bugbot completed as skipped/neutral with an unresolved finding, and this PR exceeds the low-risk approval threshold (console/CLI API routing plus Capgo cloud deploy allowlist). Reviewers are already assigned; no approval from this run.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
All reported issues were addressed across 13 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
Only cache successful /private/config responses so transient failures can recover, and stop sending anon JWT to verify_email_otp which rejects it. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Stale comment
Risk: high. Left a non-blocking comment — Cursor Bugbot completed successfully with no open findings, but this PR exceeds the medium approval threshold (broad console/CLI API routing plus Capgo cloud deploy allowlist). Reviewers are already assigned; no approval from this run.
Sent by Cursor Approval Agent: Pull Request Approver
There was a problem hiding this comment.
Stale comment
Risk: high. Left a non-blocking comment — Cursor Bugbot completed successfully with no open findings, but this PR exceeds the low-risk approval threshold (broad console/CLI API routing plus Capgo cloud deploy allowlist). Reviewers are already assigned; no approval from this run.
Sent by Cursor Approval Agent: Pull Request Approver External
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Stale comment
Risk: high. Left a non-blocking comment — Cursor Bugbot completed as skipped on this sync and still has an unresolved finding, and this PR exceeds the low-risk approval threshold (broad console/CLI API routing plus Capgo cloud deploy allowlist). Reviewers are already assigned; no approval from this run.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Stale comment
Risk: high. Left a non-blocking comment — Cursor Bugbot completed as skipped/neutral with an unresolved finding, and this PR exceeds the medium approval threshold (broad console/CLI API routing plus Capgo cloud deploy allowlist). Reviewers are already assigned; no approval from this run.
Sent by Cursor Approval Agent: Pull Request Approver
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 27bfda5. Configure here.
There was a problem hiding this comment.
Stale comment
Risk: high. Left a non-blocking comment — Cursor Bugbot completed as skipped on this sync and still has unresolved findings, and this PR exceeds the low-risk approval threshold (broad console/CLI API routing plus Capgo cloud deploy allowlist). Reviewers are already assigned; no approval from this run.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Stale comment
Risk: high. Left a non-blocking comment — Cursor Bugbot completed as skipped/neutral with 2 unresolved findings, and this PR exceeds the medium approval threshold (broad console/CLI API routing plus Capgo cloud deploy allowlist). Reviewers are already assigned; no approval from this run.
Sent by Cursor Approval Agent: Pull Request Approver
Co-authored-by: Cursor <cursoragent@cursor.com>
|
There was a problem hiding this comment.
Risk: high. Left a non-blocking comment — Cursor Bugbot completed successfully with no open findings, but this PR exceeds the medium approval threshold (broad console/CLI API routing plus Capgo cloud deploy allowlist). Reviewers are already assigned; no approval from this run.
Sent by Cursor Approval Agent: Pull Request Approver
There was a problem hiding this comment.
Risk: high. Left a non-blocking comment — Cursor Bugbot completed successfully with no open findings, but this PR exceeds the low-risk approval threshold (broad console/CLI API routing plus Capgo cloud deploy allowlist). Reviewers are already assigned; no approval from this run.
Sent by Cursor Approval Agent: Pull Request Approver External






Summary (AI generated)
supabase.functions.invokecalls throughinvokeCapgoApi→VITE_API_HOST(api.capgo.app) instead ofsb.capgo.appinvokeCapgoCliApi→hostApi/hostFilesApi(self-host still uses/functions/v1)triggersforever; keepbundle,channel,files,privateuntil 2026-10-28 for older CLIs; stop publishing console-onlyapikey,app,organization,statistics,webhooksMotivation (AI generated)
Publishing unused Capgo cloud edge functions is an infra abuse risk. Console and new CLI can talk to Cloudflare directly; old CLIs still hit Supabase invoke for a few endpoints, so those stay published for ~3 months.
Business Impact (AI generated)
Fewer Capgo cloud Supabase functions to operate and attack, without breaking existing customer CLIs during the upgrade window. Self-host full deploy is unchanged.
Test Plan (AI generated)
api.capgo.app, notsb.capgo.app/functions/v1bundle upload, channel set/delete, upload link / delete failed version / set manifest against Capgo cloud--supa-host/ self-host: same flows still hit/functions/v1bun scripts/supabase-cloud-functions.ts list)bunx vitest run tests/supabase-cloud-functions.unit.test.tsbundle/channel/files/privatefrom the allowlist and delete Capgo cloud Supabase deploymentsGenerated with AI
Made with Cursor
Summary by CodeRabbit
New Features
Deployment
Documentation
Tests