scaffolded track

This commit is contained in:
John Yeo
2026-04-14 11:04:46 +01:00
parent 973ab08e69
commit 646fe84e7d
53 changed files with 3671 additions and 427 deletions

View File

@@ -10,14 +10,12 @@ export const fullSubjectToCustomerEntitlements = ({
fullSubject,
inStatuses = [CusProductStatus.Active, CusProductStatus.PastDue],
reverseOrder = false,
featureId,
featureIds,
customerEntitlementFilters,
}: {
fullSubject: FullSubject;
inStatuses?: CusProductStatus[];
reverseOrder?: boolean;
featureId?: string;
featureIds?: string[];
customerEntitlementFilters?: CustomerEntitlementFilters;
}) => {
@@ -41,13 +39,6 @@ export const fullSubjectToCustomerEntitlements = ({
});
}
if (featureId) {
customerEntitlements = customerEntitlements.filter(
(customerEntitlement) =>
customerEntitlement.entitlement.feature.id === featureId,
);
}
if (featureIds) {
customerEntitlements = customerEntitlements.filter((customerEntitlement) =>
featureIds.includes(customerEntitlement.entitlement.feature.id),

View File

@@ -0,0 +1,28 @@
import type { DbOverageAllowed } from "../../models/cusModels/billingControls/customerBillingControls.js";
import type { FullSubject } from "../../models/cusModels/fullSubject/fullSubjectModel.js";
/** Extract overage_allowed entries for the requested features from a FullSubject. */
export const fullSubjectToOverageAllowedByFeatureId = ({
fullSubject,
featureIds,
}: {
fullSubject: FullSubject;
featureIds: string[];
}): Record<string, DbOverageAllowed> => {
const scopedOverageAllowed =
fullSubject.entity?.overage_allowed ?? fullSubject.customer.overage_allowed;
const overageAllowedByFeatureId: Record<string, DbOverageAllowed> = {};
const uniqueFeatureIds = [...new Set(featureIds)];
for (const featureId of uniqueFeatureIds) {
const overageAllowed = scopedOverageAllowed?.find(
(candidate) => candidate.feature_id === featureId,
);
if (overageAllowed) {
overageAllowedByFeatureId[featureId] = overageAllowed;
}
}
return overageAllowedByFeatureId;
};

View File

@@ -0,0 +1,68 @@
import type { DbSpendLimit } from "../../models/cusModels/billingControls/customerBillingControls.js";
import type { FullSubject } from "../../models/cusModels/fullSubject/fullSubjectModel.js";
import { cusEntToCusPrice } from "../cusEntUtils/index.js";
import { isPayPerUsePrice } from "../productUtils/priceUtils/index.js";
import { fullSubjectToCustomerEntitlements } from "./fullSubjectToCustomerEntitlements.js";
/** Extract enabled spend limits for the requested features from a FullSubject. */
export const fullSubjectToSpendLimitByFeatureId = ({
fullSubject,
featureIds,
}: {
fullSubject: FullSubject;
featureIds: string[];
}): Record<string, DbSpendLimit> => {
const scopedSpendLimits =
fullSubject.entity?.spend_limits ?? fullSubject.customer.spend_limits;
const spendLimitByFeatureId: Record<string, DbSpendLimit> = {};
const uniqueFeatureIds = [...new Set(featureIds)];
for (const featureId of uniqueFeatureIds) {
const spendLimit = scopedSpendLimits?.find(
(candidate) =>
candidate.feature_id === featureId &&
candidate.enabled &&
candidate.overage_limit !== undefined,
);
if (spendLimit) {
spendLimitByFeatureId[featureId] = spendLimit;
}
}
return spendLimitByFeatureId;
};
export const fullSubjectToUsageBasedCusEntsByFeatureId = ({
fullSubject,
featureIds,
}: {
fullSubject: FullSubject;
featureIds: string[];
}): Record<string, string[]> => {
const customerEntitlements = fullSubjectToCustomerEntitlements({
fullSubject,
featureIds,
});
const usageBasedCusEntsByFeatureId: Record<string, string[]> = {};
for (const customerEntitlement of customerEntitlements) {
const customerPrice = cusEntToCusPrice({
cusEnt: customerEntitlement,
});
if (!customerPrice || !isPayPerUsePrice({ price: customerPrice.price })) {
continue;
}
if (!usageBasedCusEntsByFeatureId[customerEntitlement.feature_id]) {
usageBasedCusEntsByFeatureId[customerEntitlement.feature_id] = [];
}
usageBasedCusEntsByFeatureId[customerEntitlement.feature_id].push(
customerEntitlement.id,
);
}
return usageBasedCusEntsByFeatureId;
};

View File

@@ -2,5 +2,10 @@ export * from "./aggregatedUtils/index.js";
export { fullCustomerToFullSubject } from "./fullCustomerToFullSubject.js";
export { fullSubjectToApiCustomerProducts } from "./fullSubjectToApiCustomerProducts.js";
export { fullSubjectToCustomerEntitlements } from "./fullSubjectToCustomerEntitlements.js";
export { fullSubjectToOverageAllowedByFeatureId } from "./fullSubjectToOverageAllowed.js";
export {
fullSubjectToSpendLimitByFeatureId,
fullSubjectToUsageBasedCusEntsByFeatureId,
} from "./fullSubjectToSpendLimit.js";
export { logFullSubject } from "./logFullSubject.js";
export { normalizedToFullSubject } from "./normalizedToFullSubject.js";