barsa 230a61c520 refactor: enhance account status handling and error messaging in auth guards
- Introduced a new `AccountStatusResult` interface to standardize account status detection across systems.
- Updated the `VerificationWorkflowService` to merge handoff data with discovered account status.
- Enhanced error handling in `GlobalAuthGuard` and `LocalAuthGuard` to include structured error codes for better clarity in unauthorized responses.
- Refined WHMCS and Salesforce integration schemas to ensure consistent data validation and coercion.
2026-03-02 18:00:41 +09:00

125 lines
3.4 KiB
TypeScript

import { parseAmount } from "../../../common/providers/whmcs-utils/index.js";
import {
whmcsCatalogProductListResponseSchema,
type WhmcsCatalogProductListResponse,
} from "./raw.types.js";
export interface WhmcsCatalogPricing {
currency: string;
prefix?: string | undefined;
suffix?: string | undefined;
monthly?: number | undefined;
quarterly?: number | undefined;
semiannually?: number | undefined;
annually?: number | undefined;
biennially?: number | undefined;
triennially?: number | undefined;
setupFees: {
monthly?: number | undefined;
quarterly?: number | undefined;
semiannually?: number | undefined;
annually?: number | undefined;
biennially?: number | undefined;
triennially?: number | undefined;
};
}
export interface WhmcsCatalogProductNormalized {
id: string;
groupId: number;
name: string;
description: string;
module: string;
payType: string;
pricing: Record<string, WhmcsCatalogPricing>;
}
const cycles = [
"monthly",
"quarterly",
"semiannually",
"annually",
"biennially",
"triennially",
] as const;
const setupFeeKeys = [
"msetupfee",
"qsetupfee",
"ssetupfee",
"asetupfee",
"bsetupfee",
"tsetupfee",
] as const;
const normalizePrice = (value: string | undefined): number | undefined =>
value === undefined ? undefined : parseAmount(value);
export function parseWhmcsCatalogProductListResponse(
raw: unknown
): WhmcsCatalogProductListResponse {
return whmcsCatalogProductListResponseSchema.parse(raw);
}
export function transformWhmcsCatalogProductsResponse(
raw: unknown
): WhmcsCatalogProductNormalized[] {
const parsed = parseWhmcsCatalogProductListResponse(raw);
const products = parsed.products.product;
return products.map(product => {
const pricingEntries = Object.entries(product.pricing ?? {});
const pricing = pricingEntries.reduce<Record<string, WhmcsCatalogPricing>>(
(acc, [currency, cyclePricing]) => {
const normalizedCycles: Partial<WhmcsCatalogPricing> = {
currency,
prefix: cyclePricing.prefix,
suffix: cyclePricing.suffix,
};
for (const cycle of cycles) {
const value = cyclePricing[cycle];
if (value !== undefined) {
normalizedCycles[cycle] = normalizePrice(value);
}
}
const setupFees: WhmcsCatalogPricing["setupFees"] = {};
for (const [index, feeKey] of setupFeeKeys.entries()) {
const value = cyclePricing[feeKey];
const cycleKey = cycles[index];
if (value !== undefined && cycleKey !== undefined) {
setupFees[cycleKey] = normalizePrice(value);
}
}
acc[currency] = {
currency,
prefix: cyclePricing.prefix,
suffix: cyclePricing.suffix,
monthly: normalizedCycles.monthly,
quarterly: normalizedCycles.quarterly,
semiannually: normalizedCycles.semiannually,
annually: normalizedCycles.annually,
biennially: normalizedCycles.biennially,
triennially: normalizedCycles.triennially,
setupFees,
};
return acc;
},
{}
);
return {
id: product.pid,
groupId: product.gid,
name: product.name,
description: product.description,
module: product.module,
payType: product.paytype,
pricing,
} satisfies WhmcsCatalogProductNormalized;
});
}