Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Tip New to Tusk? Learn more here. |
| .object({ | ||
| amount: z.number().optional(), | ||
| tiers: z.array(UsageTierSchema).optional(), | ||
| tiers_type: z.enum(TiersType).optional(), |
There was a problem hiding this comment.
TiersType is a TypeScript enum, so must use z.nativeEnum() not z.enum()
| tiers_type: z.enum(TiersType).optional(), | |
| tiers_type: z.nativeEnum(TiersType).optional(), |
Prompt To Fix With AI
This is a comment left during a code review.
Path: shared/api/products/items/apiPlanItemV1.ts
Line: 36
Comment:
`TiersType` is a TypeScript enum, so must use `z.nativeEnum()` not `z.enum()`
```suggestion
tiers_type: z.nativeEnum(TiersType).optional(),
```
How can I resolve this? If you propose a fix, please make it concise.| @@ -31,6 +34,7 @@ export const ApiPlanItemV0Schema = z | |||
| .object({ | |||
| amount: z.number().optional(), | |||
| tiers: z.array(UsageTierSchema).optional(), | |||
There was a problem hiding this comment.
TiersType is a TypeScript enum, so must use z.nativeEnum() not z.enum()
| tiers: z.array(UsageTierSchema).optional(), | |
| tiers_type: z.nativeEnum(TiersType).optional(), |
Prompt To Fix With AI
This is a comment left during a code review.
Path: shared/api/products/items/previousVersions/apiPlanItemV0.ts
Line: 36
Comment:
`TiersType` is a TypeScript enum, so must use `z.nativeEnum()` not `z.enum()`
```suggestion
tiers_type: z.nativeEnum(TiersType).optional(),
```
How can I resolve this? If you propose a fix, please make it concise.| @@ -26,6 +29,7 @@ export const CreatePlanItemParamsV1Schema = z | |||
| .object({ | |||
| amount: z.number().optional(), | |||
| tiers: z.array(UsageTierSchema).optional(), | |||
There was a problem hiding this comment.
TiersType is a TypeScript enum, so must use z.nativeEnum() not z.enum()
| tiers: z.array(UsageTierSchema).optional(), | |
| tiers_type: z.nativeEnum(TiersType).optional(), |
Prompt To Fix With AI
This is a comment left during a code review.
Path: shared/api/products/items/crud/createPlanItemParamsV1.ts
Line: 31
Comment:
`TiersType` is a TypeScript enum, so must use `z.nativeEnum()` not `z.enum()`
```suggestion
tiers_type: z.nativeEnum(TiersType).optional(),
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
1 issue found across 18 files
Confidence score: 4/5
- This PR looks safe to merge with minimal risk; the only noted issue is a low-severity guideline mismatch.
shared/models/productV2Models/productItemModels/productItemModels.tsusesz.nativeEnum, which is discouraged in Zod v4 and could lead to deprecation-related friction later.- Pay close attention to
shared/models/productV2Models/productItemModels/productItemModels.ts- update enum handling to align with repository guidance.
Prompt for AI agents (all 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="shared/models/productV2Models/productItemModels/productItemModels.ts">
<violation number="1" location="shared/models/productV2Models/productItemModels/productItemModels.ts:123">
P2: Avoid z.nativeEnum in Zod v4; use z.enum with the TypeScript enum instead to match repository guidance and avoid deprecated API.
(Based on your team's feedback about avoiding z.nativeEnum in Zod v4.) [FEEDBACK_USED]</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| "The billing units of the product item (eg $1 for 30 credits).", | ||
| }), | ||
|
|
||
| tiers_type: z.nativeEnum(TiersType).nullish().meta({ |
There was a problem hiding this comment.
P2: Avoid z.nativeEnum in Zod v4; use z.enum with the TypeScript enum instead to match repository guidance and avoid deprecated API.
(Based on your team's feedback about avoiding z.nativeEnum in Zod v4.)
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At shared/models/productV2Models/productItemModels/productItemModels.ts, line 123:
<comment>Avoid z.nativeEnum in Zod v4; use z.enum with the TypeScript enum instead to match repository guidance and avoid deprecated API.
(Based on your team's feedback about avoiding z.nativeEnum in Zod v4.) </comment>
<file context>
@@ -119,6 +120,11 @@ export const ProductItemSchema = z.object({
"The billing units of the product item (eg $1 for 30 credits).",
}),
+ tiers_type: z.nativeEnum(TiersType).nullish().meta({
+ description:
+ "The type of tiered pricing: graduated or volume-based.",
</file context>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5f685cf9a3
ℹ️ 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".
| .object({ | ||
| amount: z.number().optional(), | ||
| tiers: z.array(UsageTierSchema).optional(), | ||
| tiers_type: z.enum(TiersType).optional(), |
There was a problem hiding this comment.
Propagate
tiers_type through V1-to-V0 plan item mapping
This new tiers_type field is accepted by the V1 schema, but the shared planItemV1ToV0 mapper still omits it when constructing price (it only copies amount, tiers, interval, etc.), and both planV1ToV0 and planV1ToProductItems rely on that mapper. In V1 plan/customize flows, requests that set tiers_type: "volume" are therefore downgraded without the field, so the selected tiering mode is lost before persistence.
Useful? React with 👍 / 👎.
| value={item.tiers_type ?? TiersType.Graduated} | ||
| onValueChange={(val) => | ||
| setItem({ ...item, tiers_type: val as TiersType }) | ||
| } |
There was a problem hiding this comment.
Wire selected tier mode into Stripe tier pricing params
The editor now lets users choose tiers_type, but downstream Stripe price creation still hardcodes tiers_mode: "graduated" (e.g. in createStripePrepaid.ts, createStripeInArrear.ts, and priceToStripeCreatePriceParams.ts), so selecting “Volume-based” does not change billing behavior. This creates incorrect invoices whenever multi-tier usage pricing is configured as volume-based, because Stripe continues to apply graduated math.
Useful? React with 👍 / 👎.
| @@ -72,7 +72,10 @@ export const getCusPriceUsage = ({ | |||
| const roundedQuantity = | |||
| Math.ceil(new Decimal(usage).div(billingUnits).toNumber()) * billingUnits; | |||
There was a problem hiding this comment.
should probably Decimal().mult this for the sake of it
| import { StatusCodes } from "http-status-codes"; | ||
| import { compareBillingIntervals } from "./priceUtils/priceIntervalUtils.js"; | ||
|
|
||
| export { getPriceForOverage } from "@autumn/shared"; |
There was a problem hiding this comment.
will remove this and make callers directly import shared
Summary by cubic
Adds volume-based tiered pricing alongside graduated tiers. Users can switch tier mode in the plan editor; volume mode auto-enforces prepaid. Graduated tier amount and overage calculations are centralized in shared utils and all call sites are updated.
New Features
Migration
Written for commit 9af29ef. Summary will update on new commits.
Greptile Summary
This PR adds support for volume-based tiered pricing alongside the existing graduated pricing model. The changes introduce a new
tiers_typefield throughout the pricing system to distinguish between the two pricing strategies.Key Changes:
tiers_typefield to API schemas, mappers, and conversion functionsTiersTypeenum inusagePriceConfig.tsdefines graduated and volume-based pricing typestiers_typein the prices tableEditPlanFeatureSheet.tsxshows tier type selector when multiple tiers existtiers_typecomparison logic to price and item equality checksCritical Issue:
Three API schema files incorrectly use
z.enum(TiersType)instead ofz.nativeEnum(TiersType). SinceTiersTypeis a TypeScript enum (not a Zod enum), this will cause runtime validation errors.Confidence Score: 2/5
z.enum()instead ofz.nativeEnum()for the TypeScript enumTiersType, which will cause Zod validation to fail at runtime when clients attempt to create or update products with tiered pricing.shared/api/products/items/apiPlanItemV1.ts,shared/api/products/items/previousVersions/apiPlanItemV0.ts, andshared/api/products/items/crud/createPlanItemParamsV1.ts- all have syntax errors that must be fixedImportant Files Changed
TiersTypeenum to define graduated vs volume-based tiered pricingtiers_typeto API schema but incorrectly usesz.enum()instead ofz.nativeEnum()tiers_typeto legacy API schema with same incorrectz.enum()usagetiers_typeto create params with incorrectz.enum()instead ofz.nativeEnum()Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[User selects pricing tiers in UI] --> B[EditPlanFeatureSheet.tsx] B --> C{Multiple tiers?} C -->|Yes| D[Show TiersType selector<br/>Graduated or Volume-based] C -->|No| E[Show single tier price] D --> F[User selects tiers_type] F --> G[productItemToPlanItemV1] G --> H[API: CreatePlanItemParamsV1] H --> I[planItemV0ToProductItem] I --> J[ProductItemSchema with tiers_type] J --> K[itemToPriceAndEnt] K --> L[Price object with tiers_type] L --> M[Prices Table in Database] M --> N[priceInitUtils: pricesAreSame] N --> O{Compare tiers_type} O -->|Different| P[Prices are different] O -->|Same| Q[Check other fields]Last reviewed commit: 5f685cf