barsa ece89de49a Update TypeScript and ESLint configurations for improved type safety and compatibility
- Modified ESLint configuration to support file patterns for TypeScript files.
- Updated TypeScript configurations across multiple applications to use ES2024 and enable composite builds.
- Refactored type inference in domain modules to utilize Zod's infer type for better type safety.
- Enhanced utility functions to handle various data types more robustly, improving overall code quality.
2025-12-12 14:35:19 +09:00

135 lines
4.1 KiB
TypeScript

/**
* Orders Domain - Validation
*
* Extended business validation rules for orders.
* These rules represent domain logic and should be reusable across frontend/backend.
*/
import type { infer as ZodInfer } from "zod";
import { orderBusinessValidationSchema } from "./schema.js";
// ============================================================================
// SKU Business Rules Helpers
// ============================================================================
/**
* Check if SKUs array contains a SIM service plan
* (excludes activation fees and addons)
*/
export function hasSimServicePlan(skus: string[]): boolean {
return skus.some(
sku =>
sku.toUpperCase().includes("SIM") &&
!sku.toUpperCase().includes("ACTIVATION") &&
!sku.toUpperCase().includes("ADDON")
);
}
/**
* Check if SKUs array contains a SIM activation fee
*/
export function hasSimActivationFee(_skus: string[]): boolean {
// Deprecated: rely on catalog metadata instead of heuristics.
return true;
}
/**
* Check if SKUs array contains a VPN activation fee
*/
export function hasVpnActivationFee(skus: string[]): boolean {
return skus.some(
sku => sku.toUpperCase().includes("VPN") && sku.toUpperCase().includes("ACTIVATION")
);
}
/**
* Check if SKUs array contains an Internet service plan
* (excludes installation and addons)
*/
export function hasInternetServicePlan(skus: string[]): boolean {
return skus.some(
sku =>
sku.toUpperCase().includes("INTERNET") &&
!sku.toUpperCase().includes("INSTALL") &&
!sku.toUpperCase().includes("ADDON")
);
}
/**
* Check if SKUs array contains main service SKUs for Internet orders
* (filters out installation, addons, activation fees)
*/
export function getMainServiceSkus(skus: string[]): string[] {
return skus.filter(sku => {
const upperSku = sku.toUpperCase();
return (
!upperSku.includes("INSTALL") &&
!upperSku.includes("ADDON") &&
!upperSku.includes("ACTIVATION") &&
!upperSku.includes("FEE")
);
});
}
// ============================================================================
// Extended Order Validation with SKU Business Rules
// ============================================================================
/**
* Complete order validation including all SKU business rules
*
* This schema delegates to the helper functions above for DRY validation.
* Helper functions are reusable in both schema refinements and imperative validation.
*
* Validates:
* - Basic order structure (from orderBusinessValidationSchema)
* - SIM orders have service plan + activation fee
* - VPN orders have activation fee
* - Internet orders have service plan
*/
export const orderWithSkuValidationSchema = orderBusinessValidationSchema
.refine(data => data.orderType !== "SIM" || hasSimServicePlan(data.skus), {
message: "SIM orders must include a SIM service plan",
path: ["skus"],
})
.refine(data => data.orderType !== "VPN" || hasVpnActivationFee(data.skus), {
message: "VPN orders require an activation fee",
path: ["skus"],
})
.refine(data => data.orderType !== "Internet" || hasInternetServicePlan(data.skus), {
message: "Internet orders require a service plan",
path: ["skus"],
});
export type OrderWithSkuValidation = ZodInfer<typeof orderWithSkuValidationSchema>;
// ============================================================================
// Validation Error Messages
// ============================================================================
/**
* Get specific validation error message for order type
*/
export function getOrderTypeValidationError(orderType: string, skus: string[]): string | null {
switch (orderType) {
case "SIM":
if (!hasSimServicePlan(skus)) {
return "A SIM plan must be selected";
}
break;
case "VPN":
if (!hasVpnActivationFee(skus)) {
return "VPN orders require an activation fee";
}
break;
case "Internet":
if (!hasInternetServicePlan(skus)) {
return "Internet orders require a service plan";
}
break;
}
return null;
}