From 4b6532c16fc453f311447c11c04a0de50d60ed26 Mon Sep 17 00:00:00 2001 From: amianthus <49116958+SirTenzin@users.noreply.github.com> Date: Wed, 4 Mar 2026 10:18:59 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20only=20need=20one=20of=20?= =?UTF-8?q?amount=20or=20flat=5Famount=20or=20both?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- atmn/src/compose/models/planModels.ts | 13 ++++++++---- typegen/genUtils/TypeGenerator.ts | 1 + typegen/genUtils/atmnTypeHelpers.ts | 29 ++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/atmn/src/compose/models/planModels.ts b/atmn/src/compose/models/planModels.ts index 0dc48b44..5413c7fe 100644 --- a/atmn/src/compose/models/planModels.ts +++ b/atmn/src/compose/models/planModels.ts @@ -52,7 +52,7 @@ export const PlanItemSchema = z.object({ }), tiers: z.array(UsageTierSchema).optional().meta({ description: - "Tiered pricing. Each tier's 'to' does NOT include included amount. Either 'amount' or 'tiers' is required.", + "Tiered pricing. Either 'amount' or 'tiers' is required.", }), tier_behavior: z.union([z.literal("graduated"), z.literal("volume")]).optional(), @@ -245,7 +245,7 @@ type PriceWithAmount = PriceBaseFields & { tiers?: never; }; -// Price with graduated tiered pricing (no flat amount per tier) +// Price with graduated tiered pricing (each tier's rate applies only to units within that tier) type PriceWithGraduatedTiers = PriceBaseFields & { /** Cannot have flat amount when using tiers */ amount?: never; @@ -255,14 +255,19 @@ type PriceWithGraduatedTiers = PriceBaseFields & { tierBehavior: "graduated"; }; -// Price with volume tiered pricing (flat amount per tier) +// Volume tier: at least one of amount or flatAmount must be present +type VolumeTier = + | { to: number | "inf"; amount: number; flatAmount?: number } + | { to: number | "inf"; amount?: number; flatAmount: number }; + +// Price with volume tiered pricing (the tier the total usage falls into applies to all units) type PriceWithVolumeTiers = Omit & { /** Volume pricing does not support usage_based billing — use 'prepaid' */ billingMethod: Exclude; /** Cannot have flat amount when using tiers */ amount?: never; /** Volume tiered pricing: the tier the total usage falls into applies to all units */ - tiers: Array<{ to: number | "inf"; amount: number; flatAmount?: number }>; + tiers: Array; /** Volume: the rate of the tier the total usage falls into applies to all units */ tierBehavior: "volume"; }; diff --git a/typegen/genUtils/TypeGenerator.ts b/typegen/genUtils/TypeGenerator.ts index 0c06e05e..98da3ffa 100644 --- a/typegen/genUtils/TypeGenerator.ts +++ b/typegen/genUtils/TypeGenerator.ts @@ -284,6 +284,7 @@ ${imports} OnDecrease: ['prorate', 'refund_immediately', 'no_action'], FreeTrialDuration: ['day', 'month', 'year'], TierBehaviours: ['graduated', 'volume'], + TierBehavior: ['graduated', 'volume'], ApiFeatureType: ['static', 'boolean', 'single_use', 'continuous_use', 'credit_system'], FeatureType: ['boolean', 'metered', 'credit_system'], }; diff --git a/typegen/genUtils/atmnTypeHelpers.ts b/typegen/genUtils/atmnTypeHelpers.ts index 0b35e964..34ba5125 100644 --- a/typegen/genUtils/atmnTypeHelpers.ts +++ b/typegen/genUtils/atmnTypeHelpers.ts @@ -234,16 +234,35 @@ type PriceWithAmount = PriceBaseFields & { tiers?: never; }; -// Price with tiered pricing (no flat amount) -type PriceWithTiers = PriceBaseFields & { +// Price with graduated tiered pricing (each tier's rate applies only to units within that tier) +type PriceWithGraduatedTiers = PriceBaseFields & { /** Cannot have flat amount when using tiers */ amount?: never; - /** Tiered pricing structure based on usage ranges */ + /** Graduated tiered pricing: each tier's amount applies only to units within that tier */ tiers: Array<{ to: number | "inf"; amount: number }>; - /** Required when tiers is defined: how tiers are applied */ - tierBehaviour: "graduated" | "volume"; + /** Graduated: each tier's rate applies only to usage within that tier */ + tierBehavior: "graduated"; }; +// Volume tier: at least one of amount or flatAmount must be present +type VolumeTier = + | { to: number | "inf"; amount: number; flatAmount?: number } + | { to: number | "inf"; amount?: number; flatAmount: number }; + +// Price with volume tiered pricing (the tier the total usage falls into applies to all units) +type PriceWithVolumeTiers = Omit & { + /** Volume pricing does not support usage_based billing — use 'prepaid' */ + billingMethod: Exclude; + /** Cannot have flat amount when using tiers */ + amount?: never; + /** Volume tiered pricing: the tier the total usage falls into applies to all units */ + tiers: Array; + /** Volume: the rate of the tier the total usage falls into applies to all units */ + tierBehavior: "volume"; +}; + +type PriceWithTiers = PriceWithGraduatedTiers | PriceWithVolumeTiers; + // Price must have either amount OR tiers (not both, not neither) type PriceAmountOrTiers = PriceWithAmount | PriceWithTiers;