[codex] Share build minute pricing credits#1900
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughUpdated build-time credit prices across locale files and the database; added a typed client API and Supabase edge function support for computing build_time costs (with org-scoped pricing); refactored the Usage page to call the new estimator; added migration/seed changes and tests for build-time pricing and org overrides. Changes
Sequence DiagramsequenceDiagram
participant User
participant Vue as Usage.vue
participant Service as src/services/supabase.ts
participant EdgeFn as /private/credits
participant DB as capgo_credits_steps
User->>Vue: open usage page
Vue->>Service: calculateCreditCost({mau, bandwidth, storage, build_time})
Service->>EdgeFn: invoke edge function with request
EdgeFn->>DB: query global and org-scoped pricing tiers
DB-->>EdgeFn: return tier rows
EdgeFn->>EdgeFn: merge scoped/global steps and compute tiered costs (including build_time)
EdgeFn-->>Service: return total_cost & breakdown
Service-->>Vue: propagate response
Vue->>Vue: set estimatedUsagePrice and totalPrice
Vue-->>User: display updated estimated billing
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 19792e456c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
supabase/migrations/20260408134842_adjust_build_time_credit_pricing.sql
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
supabase/tests/32_test_usage_credits.sql (1)
44-55: Make the new pricing assertions deterministic against global tiers.Consider filtering to
org_id IS NULLso org-scoped custom tiers don’t make this test flaky.Suggested SQL refinement
SELECT results_eq( - $$SELECT price_per_unit FROM public.capgo_credits_steps WHERE type = 'build_time' AND step_min = 0$$, + $$SELECT price_per_unit + FROM public.capgo_credits_steps + WHERE type = 'build_time' + AND org_id IS NULL + AND step_min = 0 + ORDER BY step_max ASC + LIMIT 1$$, $$VALUES (0.16::double precision)$$, 'build_time credit pricing starts at $0.16 per minute' ); SELECT results_eq( - $$SELECT price_per_unit FROM public.capgo_credits_steps WHERE type = 'build_time' ORDER BY step_max DESC LIMIT 1$$, + $$SELECT price_per_unit + FROM public.capgo_credits_steps + WHERE type = 'build_time' + AND org_id IS NULL + ORDER BY step_max DESC, step_min DESC + LIMIT 1$$, $$VALUES (0.08::double precision)$$, 'build_time credit pricing floors at $0.08 per minute' );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@supabase/tests/32_test_usage_credits.sql` around lines 44 - 55, The assertions query public.capgo_credits_steps for build_time pricing but can be affected by org-scoped custom tiers; make them deterministic by adding "org_id IS NULL" to both queries (the one selecting price_per_unit WHERE type = 'build_time' AND step_min = 0 and the one ORDER BY step_max DESC LIMIT 1) so they only assert against global tiers in capgo_credits_steps.messages/ru.json (1)
611-622: Keep the numeric ladder out of locale files.These strings still duplicate the build-minute prices that other surfaces already source from
capgo_credits_steps. The next pricing change will require another 16-locale sweep and can drift from the backend again. Consider localizing only the labels/units and rendering the numeric tier values from the shared pricing source.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@messages/ru.json` around lines 611 - 622, The locale file contains hard-coded numeric pricing tiers (keys like "credits-pricing-build-tier-first-100", "credits-pricing-build-tier-next-400", "credits-pricing-build-tier-next-5000-price", etc.) which duplicates the authoritative data; remove numeric values from these keys and keep only label/unit strings, then update the UI rendering to pull the numeric tier values from the shared capgo_credits_steps source at runtime and interpolate them into the localized label; ensure keys remain stable (e.g., "credits-pricing-build-tier-first" or "credits-pricing-build-tier-label") so translators only receive unit/label text and the numeric values are rendered from capgo_credits_steps.tests/credits-pricing.test.ts (1)
10-55: Run these API tests withit.concurrent().Both cases only read pricing state / hit the stateless calculator path, so sequential
it()just slows this file down.♻️ Suggested diff
- it('returns the updated build_time tiers from the shared pricing table', async () => { + it.concurrent('returns the updated build_time tiers from the shared pricing table', async () => { @@ - it('prices build_time overage through the shared calculator endpoint', async () => { + it.concurrent('prices build_time overage through the shared calculator endpoint', async () => {Based on learnings: Applies to tests/**/*.{ts,js} : Use
it.concurrent()instead ofit()when possible to run tests in parallel within the same file, maximizing parallelism for faster CI/CD🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/credits-pricing.test.ts` around lines 10 - 55, Two tests inside describe('credits pricing API') are currently using sequential it() but are safe to run in parallel; change both it(...) calls into it.concurrent(...) for the two test cases (the one with title "returns the updated build_time tiers from the shared pricing table" and the one titled "prices build_time overage through the shared calculator endpoint") keeping their async functions, fetchWithRetry/getEndpointUrl usage, request bodies and assertions identical so they execute concurrently.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/pages/settings/organization/Usage.vue`:
- Around line 139-155: The code currently treats missing plan/quote data as
zeros, causing underreporting; change calculateCreditCost usage and downstream
math so missing currentPlan or a failed quote result in "unavailable" rather
than 0: before calling calculateCreditCost, check that currentPlan is present
(from getPlans()) and only compute overageCost if currentPlan exists; on any
error or when currentPlan is missing set estimatedUsagePrice to null/undefined
(not 0); update the totalUsagePrice/totalPrice logic that uses
estimatedUsagePrice, creditDeductions, and totalCreditDeductions so it only
folds in estimatedUsagePrice when it is a real number (otherwise treat usage
price as unavailable and surface that in the UI), and ensure
calculateCreditCost, estimatedUsagePrice, totalUsagePrice, and totalPrice all
follow this non-zero/nullable flow.
In `@supabase/functions/_backend/private/credits.ts`:
- Around line 289-290: Validate body.build_time before using: parse it into a
number (e.g., const buildTime = Number(body.build_time)), then check
Number.isFinite(buildTime) and buildTime >= 0; if the check fails, either set a
safe default (0) or return a 400 error. Replace usages/returns of the unchecked
buildTime with the validated value (e.g., validatedBuildTime) so the JSON
response at the later return point does not emit NaN or non-numeric values.
Ensure validation logic is applied wherever build_time is read/returned in this
module.
---
Nitpick comments:
In `@messages/ru.json`:
- Around line 611-622: The locale file contains hard-coded numeric pricing tiers
(keys like "credits-pricing-build-tier-first-100",
"credits-pricing-build-tier-next-400",
"credits-pricing-build-tier-next-5000-price", etc.) which duplicates the
authoritative data; remove numeric values from these keys and keep only
label/unit strings, then update the UI rendering to pull the numeric tier values
from the shared capgo_credits_steps source at runtime and interpolate them into
the localized label; ensure keys remain stable (e.g.,
"credits-pricing-build-tier-first" or "credits-pricing-build-tier-label") so
translators only receive unit/label text and the numeric values are rendered
from capgo_credits_steps.
In `@supabase/tests/32_test_usage_credits.sql`:
- Around line 44-55: The assertions query public.capgo_credits_steps for
build_time pricing but can be affected by org-scoped custom tiers; make them
deterministic by adding "org_id IS NULL" to both queries (the one selecting
price_per_unit WHERE type = 'build_time' AND step_min = 0 and the one ORDER BY
step_max DESC LIMIT 1) so they only assert against global tiers in
capgo_credits_steps.
In `@tests/credits-pricing.test.ts`:
- Around line 10-55: Two tests inside describe('credits pricing API') are
currently using sequential it() but are safe to run in parallel; change both
it(...) calls into it.concurrent(...) for the two test cases (the one with title
"returns the updated build_time tiers from the shared pricing table" and the one
titled "prices build_time overage through the shared calculator endpoint")
keeping their async functions, fetchWithRetry/getEndpointUrl usage, request
bodies and assertions identical so they execute concurrently.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: eb837678-5373-4b4f-92ac-a241a42b3714
📒 Files selected for processing (22)
messages/de.jsonmessages/en.jsonmessages/es.jsonmessages/fr.jsonmessages/hi.jsonmessages/id.jsonmessages/it.jsonmessages/ja.jsonmessages/ko.jsonmessages/pl.jsonmessages/pt-br.jsonmessages/ru.jsonmessages/tr.jsonmessages/vi.jsonmessages/zh-cn.jsonsrc/pages/settings/organization/Usage.vuesrc/services/supabase.tssupabase/functions/_backend/private/credits.tssupabase/migrations/20260408134842_adjust_build_time_credit_pricing.sqlsupabase/seed.sqlsupabase/tests/32_test_usage_credits.sqltests/credits-pricing.test.ts
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/pages/settings/organization/Usage.vue (1)
97-120:⚠️ Potential issue | 🟠 MajorOnly prefer deductions when one overlaps the active billing cycle.
totalCreditDeductionsis cycle-filtered, but Line 155 switches to deductions whenevercreditDeductions.length > 0. A historical row makes this branch win even when the current-cycle total is still0, so the estimate is suppressed until the first deduction for the new cycle lands.Also applies to: 155-156
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/settings/organization/Usage.vue` around lines 97 - 120, The current logic uses creditDeductions.length to decide whether to prefer deductions (causing historical deductions to suppress estimates); change the decision to use the cycle-filtered total (totalCreditDeductions) or an explicit check for any deduction that overlaps the active billing cycle (using billingStart/billingEnd and the same overlap logic applied when computing totalCreditDeductions). Update the branch that currently checks creditDeductions.length > 0 (around the decision at lines ~155-156) to instead check totalCreditDeductions > 0 or a filtered list of deductions that overlap the billing window so only current-cycle deductions affect the UI.
♻️ Duplicate comments (1)
src/pages/settings/organization/Usage.vue (1)
138-156:⚠️ Potential issue | 🟠 MajorStill folding unavailable pricing into
$0.If
currentPlanis missing, this path prices usage against zero included units and also dropsbasePriceto0; ifcalculateCreditCost()fails,estimatedUsagePricestill stays0. The page then shows a concrete total when the inputs were actually unavailable.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/settings/organization/Usage.vue` around lines 138 - 156, The code currently treats missing plan data or a failed calculateCreditCost() as $0; change logic in the Usage.vue block around currentPlan, estimatedUsagePrice, calculateCreditCost, totalUsagePrice and totalPrice so that missing/failed pricing produces an "unavailable" state rather than folding into zeros: detect when currentPlan is null/undefined and set a pricingUnavailable flag (or set estimatedUsagePrice to null/undefined) before calling calculateCreditCost; wrap the await calculateCreditCost call in try/catch and on error set pricingUnavailable (or leave estimatedUsagePrice null) instead of leaving it at 0; then compute totalUsagePrice and totalPrice only when pricingUnavailable is false (otherwise propagate null/undefined or a sentinel so the UI can show N/A/placeholder instead of a numeric $0).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/pages/settings/organization/Usage.vue`:
- Around line 97-120: The current logic uses creditDeductions.length to decide
whether to prefer deductions (causing historical deductions to suppress
estimates); change the decision to use the cycle-filtered total
(totalCreditDeductions) or an explicit check for any deduction that overlaps the
active billing cycle (using billingStart/billingEnd and the same overlap logic
applied when computing totalCreditDeductions). Update the branch that currently
checks creditDeductions.length > 0 (around the decision at lines ~155-156) to
instead check totalCreditDeductions > 0 or a filtered list of deductions that
overlap the billing window so only current-cycle deductions affect the UI.
---
Duplicate comments:
In `@src/pages/settings/organization/Usage.vue`:
- Around line 138-156: The code currently treats missing plan data or a failed
calculateCreditCost() as $0; change logic in the Usage.vue block around
currentPlan, estimatedUsagePrice, calculateCreditCost, totalUsagePrice and
totalPrice so that missing/failed pricing produces an "unavailable" state rather
than folding into zeros: detect when currentPlan is null/undefined and set a
pricingUnavailable flag (or set estimatedUsagePrice to null/undefined) before
calling calculateCreditCost; wrap the await calculateCreditCost call in
try/catch and on error set pricingUnavailable (or leave estimatedUsagePrice
null) instead of leaving it at 0; then compute totalUsagePrice and totalPrice
only when pricingUnavailable is false (otherwise propagate null/undefined or a
sentinel so the UI can show N/A/placeholder instead of a numeric $0).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a4544dae-bfdd-4df8-911e-752fa86c3adb
📒 Files selected for processing (5)
src/pages/settings/organization/Usage.vuesrc/services/supabase.tssupabase/functions/_backend/private/credits.tssupabase/migrations/20260408134842_adjust_build_time_credit_pricing.sqltests/credits-pricing.test.ts
✅ Files skipped from review due to trivial changes (1)
- supabase/migrations/20260408134842_adjust_build_time_credit_pricing.sql
🚧 Files skipped from review as they are similar to previous changes (2)
- supabase/functions/_backend/private/credits.ts
- tests/credits-pricing.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6920ee1e7a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
supabase/migrations/20260408134842_adjust_build_time_credit_pricing.sql
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bc88606f92
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
supabase/functions/_backend/private/credits.ts (1)
344-352:⚠️ Potential issue | 🟡 MinorDon't collapse auth failures into
failed_to_fetch_pricing_data.Line 351 rewraps every exception from
getScopedCreditSteps(). For org-scoped requests, that hides the existingnot_authorizederror and makes callers treat an auth problem like a pricing outage.💡 Proposed fix
app.get('/', async (c) => { - try { - const orgId = c.req.query('org_id') ?? undefined - const credits = await getScopedCreditSteps(c as AppContext, orgId) - return c.json(credits) - } - catch (e) { - throw simpleError('failed_to_fetch_pricing_data', 'Failed to fetch pricing data', {}, e) - } + const orgId = c.req.query('org_id') ?? undefined + const credits = await getScopedCreditSteps(c as AppContext, orgId) + return c.json(credits) })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@supabase/functions/_backend/private/credits.ts` around lines 344 - 352, The current app.get('/') handler wraps all exceptions from getScopedCreditSteps(...) into a generic simpleError('failed_to_fetch_pricing_data', ...), which hides authorization errors; update the catch to detect if the caught error is the existing not_authorized error (e.g., check error.code or error.name as used elsewhere) and rethrow it unchanged, otherwise wrap non-auth errors with simpleError('failed_to_fetch_pricing_data', ...); reference the app.get('/', ...) route, getScopedCreditSteps, and the simpleError('failed_to_fetch_pricing_data', ...) call when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@supabase/functions/_backend/private/credits.ts`:
- Around line 79-105: The GET handler currently swallows all errors from
getScopedCreditSteps() into a generic 'failed_to_fetch_pricing_data'—change the
handler to rethrow or return not_authorized errors unchanged (i.e., if
err.message === 'not_authorized' or err.name indicates auth, propagate it) and
only map other errors to the generic failure; in addition, update
preferScopedCreditSteps(steps, orgId) to detect mismatched boundaries between
global and org-scoped rows for the same type (e.g., when a type has both
org-scoped and global entries with differing step_min/step_max), and either
throw a descriptive error or surface a validation warning so org-scoped tiers
aren’t silently dropped (alternatively enforce uniqueness/validation at insert
as suggested—e.g., add a DB uniqueness constraint or insert-time validation to
ensure org-scoped step boundaries match global boundaries).
---
Outside diff comments:
In `@supabase/functions/_backend/private/credits.ts`:
- Around line 344-352: The current app.get('/') handler wraps all exceptions
from getScopedCreditSteps(...) into a generic
simpleError('failed_to_fetch_pricing_data', ...), which hides authorization
errors; update the catch to detect if the caught error is the existing
not_authorized error (e.g., check error.code or error.name as used elsewhere)
and rethrow it unchanged, otherwise wrap non-auth errors with
simpleError('failed_to_fetch_pricing_data', ...); reference the app.get('/',
...) route, getScopedCreditSteps, and the
simpleError('failed_to_fetch_pricing_data', ...) call when making the change.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 153a9067-72a9-4198-a450-6810874d2854
📒 Files selected for processing (5)
src/pages/settings/organization/Usage.vuesupabase/functions/_backend/private/credits.tssupabase/migrations/20260408134842_adjust_build_time_credit_pricing.sqlsupabase/tests/32_test_usage_credits.sqltests/credits-pricing.test.ts
✅ Files skipped from review due to trivial changes (1)
- tests/credits-pricing.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- supabase/migrations/20260408134842_adjust_build_time_credit_pricing.sql
- supabase/tests/32_test_usage_credits.sql
- src/pages/settings/organization/Usage.vue
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
🧹 Nitpick comments (2)
supabase/functions/_backend/private/credits.ts (2)
139-139: Redundant filter on already-typed group.The
filter(step => step.type === type)is unnecessary sincegroup.scopedonly contains steps of the currenttype(populated at lines 125-133).♻️ Suggested simplification
- const scopedSteps = sortCreditSteps(group.scoped.filter(step => step.type === type)) + const scopedSteps = sortCreditSteps(group.scoped)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@supabase/functions/_backend/private/credits.ts` at line 139, The code unnecessarily filters group.scoped by step.type even though group.scoped is already built to contain only steps of the current type; update the consumer to call sortCreditSteps(group.scoped) instead of sortCreditSteps(group.scoped.filter(step => step.type === type)) (modify the assignment to scopedSteps) so you avoid redundant filtering and extra work when computing scopedSteps.
160-164: Extract nested ternary for readability.Per SonarCloud, the nested ternary makes the authorization flow harder to follow. Consider extracting to explicit conditionals.
♻️ Suggested refactor
- const pricingClient = orgId - ? authorization - ? supabaseClient(c, authorization) - : undefined - : supabaseAdmin(c) + let pricingClient: ReturnType<typeof supabaseAdmin> | undefined + if (orgId) { + if (authorization) + pricingClient = supabaseClient(c, authorization) + } + else { + pricingClient = supabaseAdmin(c) + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@supabase/functions/_backend/private/credits.ts` around lines 160 - 164, The nested ternary used to set pricingClient (checking orgId and authorization) is hard to read; replace it with an explicit conditional assignment: declare pricingClient let/const above and then use if/else blocks to implement the same logic (if orgId is truthy -> if authorization truthy -> pricingClient = supabaseClient(c, authorization) else pricingClient = undefined; else pricingClient = supabaseAdmin(c)). Keep the same variable names (pricingClient, orgId, authorization, supabaseClient, supabaseAdmin, and c) and preserve identical runtime behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@supabase/functions/_backend/private/credits.ts`:
- Line 139: The code unnecessarily filters group.scoped by step.type even though
group.scoped is already built to contain only steps of the current type; update
the consumer to call sortCreditSteps(group.scoped) instead of
sortCreditSteps(group.scoped.filter(step => step.type === type)) (modify the
assignment to scopedSteps) so you avoid redundant filtering and extra work when
computing scopedSteps.
- Around line 160-164: The nested ternary used to set pricingClient (checking
orgId and authorization) is hard to read; replace it with an explicit
conditional assignment: declare pricingClient let/const above and then use
if/else blocks to implement the same logic (if orgId is truthy -> if
authorization truthy -> pricingClient = supabaseClient(c, authorization) else
pricingClient = undefined; else pricingClient = supabaseAdmin(c)). Keep the same
variable names (pricingClient, orgId, authorization, supabaseClient,
supabaseAdmin, and c) and preserve identical runtime behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d9adefe2-da3a-4625-89bc-1bac49982a0f
📒 Files selected for processing (2)
supabase/functions/_backend/private/credits.tstests/credits-pricing.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/credits-pricing.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c1b2745f60
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5aca3a1617
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8271140a75
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@copilot resolve conflcit |
Co-authored-by: riderx <4084527+riderx@users.noreply.github.com>
Resolved the merge conflict in |
|




Summary (AI generated)
Motivation (AI generated)
Build minutes were still using a separate fixed-price path while MAU, storage, and bandwidth already relied on the shared credit system. Moving build minutes onto the same pricing engine removes duplicated pricing logic and lets the dashboard, backend, and database all compute overage consistently.
Business Impact (AI generated)
This lowers build-minute pricing to the requested range while keeping the billing logic centralized. It reduces the risk of mismatched prices between the product surface and backend charging rules, which directly affects customer trust and revenue accuracy.
Test Plan (AI generated)
bun lintbun lint:backendbun typecheckbun run supabase:with-env -- bunx vitest run tests/credits-pricing.test.ts tests/build_time_tracking.test.ts tests/overage-tracking.test.tsbun scripts/supabase-worktree.ts test dbScreenshots (AI generated)
Credits Pricing UI
Generated with AI
Summary by CodeRabbit
Chores
Bug Fixes
Tests