import { z } from "zod/v4"; import { DbSpendLimitSchema } from "../../models/cusModels/billingControls/spendLimit.js"; import { ApiOverageAllowedSchema } from "./overageAllowed.js"; import { ApiSpendLimitSchema } from "./spendLimit.js"; import { ApiUsageAlertSchema } from "./usageAlert.js"; export const ApiEntityBillingControlsSchema = z.object({ spend_limits: z.array(ApiSpendLimitSchema).optional().meta({ description: "List of spend limits per feature. Each entry caps overage (overage_limit) and/or windowed usage (usage_limit).", }), usage_alerts: z.array(ApiUsageAlertSchema).optional().meta({ description: "List of usage alert configurations per feature.", }), overage_allowed: z.array(ApiOverageAllowedSchema).optional().meta({ description: "List of overage allowed controls per feature. When enabled, usage can exceed balance.", }), }); const ApiEntityBillingControlsParamsBaseSchema = z.object({ spend_limits: z.array(DbSpendLimitSchema).optional().meta({ description: "List of spend limits per feature. Each entry caps overage (overage_limit) and/or windowed usage (usage_limit).", }), usage_alerts: z.array(ApiUsageAlertSchema).optional().meta({ description: "List of usage alert configurations per feature.", }), overage_allowed: z.array(ApiOverageAllowedSchema).optional().meta({ description: "List of overage allowed controls per feature. When enabled, usage can exceed balance.", }), }); export const ApiEntityBillingControlsParamsSchema = ApiEntityBillingControlsParamsBaseSchema.check((ctx) => { const billingControls = ctx.value; const spendLimitFeatureIds = new Set(); for (const [index, spendLimit] of ( billingControls.spend_limits ?? [] ).entries()) { if (!spendLimit.feature_id) { continue; } if (spendLimitFeatureIds.has(spendLimit.feature_id)) { ctx.issues.push({ code: "custom", message: "Only one spend limit entry is allowed per feature_id", input: spendLimit.feature_id, path: ["spend_limits", index, "feature_id"], }); return; } spendLimitFeatureIds.add(spendLimit.feature_id); } const overageAllowedFeatureIds = new Set(); for (const [index, overageAllowed] of ( billingControls.overage_allowed ?? [] ).entries()) { if (overageAllowedFeatureIds.has(overageAllowed.feature_id)) { ctx.issues.push({ code: "custom", message: "Only one overage_allowed entry is allowed per feature_id", input: overageAllowed.feature_id, path: ["overage_allowed", index, "feature_id"], }); return; } overageAllowedFeatureIds.add(overageAllowed.feature_id); } }); export type ApiEntityBillingControls = z.infer< typeof ApiEntityBillingControlsSchema >; export type ApiEntityBillingControlsParams = z.input< typeof ApiEntityBillingControlsParamsSchema >;