feat(builder): dedicated native builder request, worker UI, and pool routing#2740
feat(builder): dedicated native builder request, worker UI, and pool routing#2740riderx wants to merge 7 commits into
Conversation
Let orgs request a dedicated native builder, track provisioning status, prefer that pool for builds with shared fallback, and surface worker state in organization settings and build history. Co-authored-by: Martin DONADIEU <martindonadieu@gmail.com>
📝 WalkthroughWalkthroughAdds dedicated native builder lifecycle management, database contracts, private API endpoints, dedicated/shared build routing, organization settings, dashboard messaging, and builder-pool visibility. ChangesDedicated native builder
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant OrganizationUser
participant DedicatedBuilderPage
participant dedicated_builder
participant dedicated_builders
OrganizationUser->>DedicatedBuilderPage: request or update builder
DedicatedBuilderPage->>dedicated_builder: authenticated API call
dedicated_builder->>dedicated_builders: validate and mutate lifecycle record
dedicated_builders-->>dedicated_builder: updated builder state
dedicated_builder-->>DedicatedBuilderPage: public builder view
DedicatedBuilderPage-->>OrganizationUser: render lifecycle status
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
Visual diff passedVisual changesGenerated at 2026-07-23T16:00:20.797Z. Threshold: 0.1% pixel difference.
Commit: Open |
Merging this PR will not alter performance
Comparing Footnotes
|
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_299be9fd-af6d-4a07-bbe3-c01e3b0db903) |
There was a problem hiding this comment.
Stale comment
Risk: high. Cursor Bugbot did not complete (skipped due to usage limit), so automated review is unavailable. Human review is required for the migration, build routing, and dedicated-builder API/UI changes. Reviewers assigned.
Sent by Cursor Approval Agent: Pull Request Approver External
Use `.some` for tab presence checks and split PATCH handlers to lower cognitive complexity. Co-authored-by: Martin DONADIEU <martindonadieu@gmail.com>
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_8a618dbd-cdf3-465d-b4e3-e54765e1c784) |
There was a problem hiding this comment.
Stale comment
Risk: high. Cursor Bugbot did not complete successfully (skipped due to usage limit), so automated review coverage is missing. Human review is required for the migration, build routing, and dedicated-builder API/UI changes. Reviewers are already assigned.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Stale comment
Risk: high. Cursor Bugbot did not complete (skipped due to usage limit), so automated review coverage is missing. Human review is still required for the migration, build routing, and dedicated-builder API/UI changes. Reviewers are already assigned.
Sent by Cursor Approval Agent: Pull Request Approver
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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/private/dedicated_builder.ts`:
- Around line 44-48: Update requireUpdateBilling to throw the quickError result
when the org.update_billing permission check fails, matching the enforcement
behavior of requireReadBilling and ensuring unauthorized callers cannot reach
the POST/PATCH mutation paths.
In `@supabase/migrations/20260723144749_dedicated_native_builder.sql`:
- Line 28: Constrain the platforms column in the dedicated native builder
migration with a database-level CHECK constraint requiring every array element
to be either "ios" or "android". Apply the same constraint to the related
definitions referenced in the additional locations, while preserving the
existing NOT NULL and empty-array default.
- Around line 11-16: Update the ADD CONSTRAINT statement for
build_requests_builder_pool_check to include NOT VALID, avoiding immediate
validation and the blocking table scan while preserving the existing CHECK
expression.
🪄 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: bb5fdb8a-b7f1-42c1-8472-255cab40143b
📒 Files selected for processing (20)
cli/src/types/supabase.types.tscloudflare_workers/api/index.tsmessages/en.jsonsrc/components/dashboard/DedicatedBuilderBanner.vuesrc/components/tables/BuildTable.vuesrc/constants/organizationTabs.tssrc/layouts/settings.vuesrc/pages/app/[app].builds.vuesrc/pages/settings/organization/DedicatedBuilder.vuesrc/pages/settings/organization/Plans.vuesrc/services/dedicatedBuilder.tssrc/types/supabase.types.tssupabase/functions/_backend/private/dedicated_builder.tssupabase/functions/_backend/public/build/request.tssupabase/functions/_backend/utils/dedicated_builder.tssupabase/functions/_backend/utils/supabase.types.tssupabase/functions/private/index.tssupabase/migrations/20260723144749_dedicated_native_builder.sqltests/builder-payload.unit.test.tstests/dedicated-builder.unit.test.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
Cap-go/capacitor-updater(manual)
Make billing guards explicitly throw, add builder_pool CHECK as NOT VALID to avoid a blocking scan, and constrain dedicated builder platforms. Co-authored-by: Martin DONADIEU <martindonadieu@gmail.com>
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_12ca8c8e-1f9c-4f51-98ea-0434e421f59d) |
There was a problem hiding this comment.
Stale comment
Risk: high. Cursor Bugbot did not complete successfully (skipped due to usage limit), so automated review coverage is missing. Human review is still required for the migration, build routing, and dedicated-builder API/UI changes; reviewers are already assigned.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Stale comment
Risk: high. Cursor Bugbot did not complete (skipped due to usage limit), so automated review coverage is missing. Human review is still required for the migration, build routing, and dedicated-builder API/UI changes. Reviewers are already assigned.
Sent by Cursor Approval Agent: Pull Request Approver
There was a problem hiding this comment.
All reported issues were addressed
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Guard stale org loads, resolve banner org by app, surface invoke error codes, avoid false idle/busy from preferred-pool counts, and render pool badges via DataTable renderFunction. Co-authored-by: Martin DONADIEU <martindonadieu@gmail.com>
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_565850c3-6fe1-4f66-8dc4-29138647dd41) |
There was a problem hiding this comment.
Stale comment
Risk: high. Cursor Bugbot did not complete successfully (skipped due to usage limit), so automated review coverage is missing. Human review is still required for the migration, build routing, and dedicated-builder API/UI changes; reviewers are already assigned.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Stale comment
Risk: high. Cursor Bugbot did not complete successfully (skipped due to usage limit), so automated review coverage is missing. Human review is still required for the migration, build routing, and dedicated-builder API/UI changes. Reviewers are already assigned.
Sent by Cursor Approval Agent: Pull Request Approver
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/components/dashboard/DedicatedBuilderBanner.vue (1)
86-87: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winPreserve the resolved organization when opening settings.
Line 87 navigates without the organization resolved from
appId. When this app belongs to a non-selected organization, the banner shows that app’s builder state but the CTA opens the selected organization’s dedicated-builder settings. Retain the resolvedorgIdand pass/select it through the settings navigation flow.🤖 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/components/dashboard/DedicatedBuilderBanner.vue` around lines 86 - 87, Update goToDedicatedBuilder to preserve the organization resolved from appId when navigating to dedicated-builder settings. Pass the resolved orgId through the router navigation so the settings view opens for that organization instead of the currently selected one, using the existing settings navigation parameter or selection mechanism.supabase/functions/_backend/utils/dedicated_builder.ts (1)
49-58: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRespect the dedicated builder’s supported platforms.
An active iOS-only dedicated pool is currently selected for Android builds because routing never evaluates
row.platforms.
supabase/functions/_backend/utils/dedicated_builder.ts#L49-L58: accept the requested platform and returnnullwhen the pool does not support it.supabase/functions/_backend/public/build/request.ts#L482-L506: pass the validatedplatforminto dedicated-pool routing.tests/dedicated-builder.unit.test.ts#L51-L89: cover supported-platform routing and unsupported-platform fallback.🤖 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/utils/dedicated_builder.ts` around lines 49 - 58, Update toDedicatedPoolRouting to accept the validated requested platform and return null when row.platforms does not include it, while preserving existing active-builder checks and routing fields. In supabase/functions/_backend/public/build/request.ts lines 482-506, pass platform to the routing call. In tests/dedicated-builder.unit.test.ts lines 51-89, add coverage for supported-platform routing and unsupported-platform fallback.
🤖 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 `@src/components/tables/BuildTable.vue`:
- Around line 328-337: Add an accessible name to the icon-only button in the
BuildTable render block by providing a descriptive aria-label that tells
screen-reader users it opens the full error details. Keep the existing click
behavior and IconEye rendering unchanged.
In `@src/pages/settings/organization/DedicatedBuilder.vue`:
- Line 45: Update the canReadBilling permission watcher around
loadDedicatedBuilder so it invokes the loader on both true and false
transitions, rather than only when permission is granted. Reuse the existing
no-permission branch in loadDedicatedBuilder to clear dedicatedBuilder and
increment loadToken, ensuring in-flight responses fail the token check after
read access is revoked.
In `@supabase/migrations/20260723144749_dedicated_native_builder.sql`:
- Line 9: Update the migration’s column comments and the line 18 ANY expression
to satisfy SQLFluff: wrap long comment text across lines without changing its
meaning, and format the ANY(...) usage according to the configured SQL style.
Keep the migration behavior and schema unchanged.
---
Outside diff comments:
In `@src/components/dashboard/DedicatedBuilderBanner.vue`:
- Around line 86-87: Update goToDedicatedBuilder to preserve the organization
resolved from appId when navigating to dedicated-builder settings. Pass the
resolved orgId through the router navigation so the settings view opens for that
organization instead of the currently selected one, using the existing settings
navigation parameter or selection mechanism.
In `@supabase/functions/_backend/utils/dedicated_builder.ts`:
- Around line 49-58: Update toDedicatedPoolRouting to accept the validated
requested platform and return null when row.platforms does not include it, while
preserving existing active-builder checks and routing fields. In
supabase/functions/_backend/public/build/request.ts lines 482-506, pass platform
to the routing call. In tests/dedicated-builder.unit.test.ts lines 51-89, add
coverage for supported-platform routing and unsupported-platform fallback.
🪄 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: 0a5813ad-3aa2-4d66-9b08-64ad3870ee5f
📒 Files selected for processing (14)
cli/src/types/supabase.types.tsmessages/en.jsonsrc/components/dashboard/DedicatedBuilderBanner.vuesrc/components/tables/BuildTable.vuesrc/pages/app/[app].builds.vuesrc/pages/settings/organization/DedicatedBuilder.vuesrc/services/dedicatedBuilder.tssrc/types/supabase.types.tssupabase/functions/_backend/private/dedicated_builder.tssupabase/functions/_backend/public/build/request.tssupabase/functions/_backend/utils/dedicated_builder.tssupabase/functions/_backend/utils/supabase.types.tssupabase/migrations/20260723144749_dedicated_native_builder.sqltests/dedicated-builder.unit.test.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
Cap-go/capacitor-updater(manual)
Co-authored-by: Martin DONADIEU <martindonadieu@gmail.com>
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_6db56c89-a289-4b7f-ba0d-2d24a5fedfae) |
Co-authored-by: Martin DONADIEU <martindonadieu@gmail.com>
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_6363c7b0-5880-4469-a6c9-0bc4e8a40bc3) |
Co-authored-by: Martin DONADIEU <martindonadieu@gmail.com>
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_243ec378-7a77-4c35-a8f9-0c6d6f459d4e) |
There was a problem hiding this comment.
Risk: high. Cursor Bugbot did not complete successfully (skipped due to usage limit), so automated review coverage is missing. Human review is still required for the migration, build routing, and dedicated-builder API/UI changes. Reviewers are already assigned.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Risk: high. Cursor Bugbot did not complete successfully (skipped due to usage limit), so automated review coverage is missing. Human review is still required for the migration, build routing, and dedicated-builder API/UI changes; reviewers are already assigned.
Sent by Cursor Approval Agent: Pull Request Approver
|





Summary (AI generated)
dedicated_buildersand preferred pool onbuild_requests.builder_poolMotivation (AI generated)
Customers with high native-build volume need a dedicated worker/pool for isolation and queue priority, while still falling back to Capgo shared builders when their worker is busy.
Business Impact (AI generated)
Enables an Enterprise-ready dedicated builder offering: self-serve request flow, clear provisioning/worker status, and fallback controls without blocking day-to-day builds.
Test Plan (AI generated)
Visual (AI generated)
Generated with AI
Summary by CodeRabbit
New Features
UI Improvements
Tests