197 lines
6.7 KiB
TypeScript
Raw Normal View History

/**
* SIM Domain - Schemas
*/
import { z } from "zod";
export const simStatusSchema = z.enum(["active", "suspended", "cancelled", "pending"]);
export const simTypeSchema = z.enum(["standard", "nano", "micro", "esim"]);
export const simDetailsSchema = z.object({
account: z.string(),
status: simStatusSchema,
planCode: z.string(),
planName: z.string(),
simType: simTypeSchema,
iccid: z.string(),
eid: z.string(),
msisdn: z.string(),
imsi: z.string(),
remainingQuotaMb: z.number(),
remainingQuotaKb: z.number(),
voiceMailEnabled: z.boolean(),
callWaitingEnabled: z.boolean(),
internationalRoamingEnabled: z.boolean(),
networkType: z.string(),
activatedAt: z.string().optional(),
expiresAt: z.string().optional(),
});
export const recentDayUsageSchema = z.object({
date: z.string(),
usageKb: z.number(),
usageMb: z.number(),
});
export const simUsageSchema = z.object({
account: z.string(),
todayUsageMb: z.number(),
todayUsageKb: z.number(),
monthlyUsageMb: z.number().optional(),
monthlyUsageKb: z.number().optional(),
recentDaysUsage: z.array(recentDayUsageSchema),
isBlacklisted: z.boolean(),
lastUpdated: z.string().optional(),
});
export const simTopUpHistoryEntrySchema = z.object({
quotaKb: z.number(),
quotaMb: z.number(),
addedDate: z.string(),
expiryDate: z.string(),
campaignCode: z.string(),
});
export const simTopUpHistorySchema = z.object({
account: z.string(),
totalAdditions: z.number(),
additionCount: z.number(),
history: z.array(simTopUpHistoryEntrySchema),
});
// ============================================================================
// SIM Management Request Schemas
// ============================================================================
export const simTopUpRequestSchema = z.object({
quotaMb: z
.number()
.int()
.min(100, "Quota must be at least 100MB")
.max(51200, "Quota must be 50GB or less"),
});
export const simPlanChangeRequestSchema = z.object({
newPlanCode: z.string().min(1, "New plan code is required"),
assignGlobalIp: z.boolean().optional(),
scheduledAt: z
.string()
.regex(/^\d{8}$/, "Scheduled date must be in YYYYMMDD format")
.optional(),
});
export const simCancelRequestSchema = z.object({
scheduledAt: z
.string()
.regex(/^\d{8}$/, "Scheduled date must be in YYYYMMDD format")
.optional(),
});
export const simTopUpHistoryRequestSchema = z.object({
fromDate: z
.string()
.regex(/^\d{8}$/, "From date must be in YYYYMMDD format"),
toDate: z
.string()
.regex(/^\d{8}$/, "To date must be in YYYYMMDD format"),
});
export const simFeaturesUpdateRequestSchema = z.object({
voiceMailEnabled: z.boolean().optional(),
callWaitingEnabled: z.boolean().optional(),
internationalRoamingEnabled: z.boolean().optional(),
networkType: z.enum(["4G", "5G"]).optional(),
});
// ============================================================================
// SIM Order Activation Schemas
// ============================================================================
export const simOrderActivationMnpSchema = z.object({
reserveNumber: z.string().min(1, "Reserve number is required"),
reserveExpireDate: z.string().regex(/^\d{8}$/, "Reserve expire date must be in YYYYMMDD format"),
account: z.string().optional(),
firstnameKanji: z.string().optional(),
lastnameKanji: z.string().optional(),
firstnameZenKana: z.string().optional(),
lastnameZenKana: z.string().optional(),
gender: z.string().optional(),
birthday: z.string().regex(/^\d{8}$/, "Birthday must be in YYYYMMDD format").optional(),
});
export const simOrderActivationAddonsSchema = z.object({
voiceMail: z.boolean().optional(),
callWaiting: z.boolean().optional(),
});
export const simOrderActivationRequestSchema = z.object({
planSku: z.string().min(1, "Plan SKU is required"),
simType: z.enum(["eSIM", "Physical SIM"]),
eid: z.string().min(15, "EID must be at least 15 characters").optional(),
activationType: z.enum(["Immediate", "Scheduled"]),
scheduledAt: z.string().regex(/^\d{8}$/, "Scheduled date must be in YYYYMMDD format").optional(),
addons: simOrderActivationAddonsSchema.optional(),
mnp: simOrderActivationMnpSchema.optional(),
msisdn: z.string().min(1, "Phone number (msisdn) is required"),
oneTimeAmountJpy: z.number().nonnegative("One-time amount must be non-negative"),
monthlyAmountJpy: z.number().nonnegative("Monthly amount must be non-negative"),
}).refine(
(data) => {
// If simType is eSIM, eid is required
if (data.simType === "eSIM" && (!data.eid || data.eid.length < 15)) {
return false;
}
return true;
},
{
message: "EID is required for eSIM and must be at least 15 characters",
path: ["eid"],
}
).refine(
(data) => {
// If activationType is Scheduled, scheduledAt is required
if (data.activationType === "Scheduled" && !data.scheduledAt) {
return false;
}
return true;
},
{
message: "Scheduled date is required for Scheduled activation",
path: ["scheduledAt"],
}
);
export type SimOrderActivationRequest = z.infer<typeof simOrderActivationRequestSchema>;
export type SimOrderActivationMnp = z.infer<typeof simOrderActivationMnpSchema>;
export type SimOrderActivationAddons = z.infer<typeof simOrderActivationAddonsSchema>;
// Legacy aliases for backward compatibility
export const simTopupRequestSchema = simTopUpRequestSchema;
export type SimTopupRequest = SimTopUpRequest;
export const simChangePlanRequestSchema = simPlanChangeRequestSchema;
export type SimChangePlanRequest = SimPlanChangeRequest;
export const simFeaturesRequestSchema = simFeaturesUpdateRequestSchema;
export type SimFeaturesRequest = SimFeaturesUpdateRequest;
// ============================================================================
// Inferred Types from Schemas (Schema-First Approach)
// ============================================================================
export type SimStatus = z.infer<typeof simStatusSchema>;
export type SimType = z.infer<typeof simTypeSchema>;
export type SimDetails = z.infer<typeof simDetailsSchema>;
export type RecentDayUsage = z.infer<typeof recentDayUsageSchema>;
export type SimUsage = z.infer<typeof simUsageSchema>;
export type SimTopUpHistoryEntry = z.infer<typeof simTopUpHistoryEntrySchema>;
export type SimTopUpHistory = z.infer<typeof simTopUpHistorySchema>;
// Request types (derived from request schemas)
export type SimTopUpRequest = z.infer<typeof simTopUpRequestSchema>;
export type SimPlanChangeRequest = z.infer<typeof simPlanChangeRequestSchema>;
export type SimCancelRequest = z.infer<typeof simCancelRequestSchema>;
export type SimTopUpHistoryRequest = z.infer<typeof simTopUpHistoryRequestSchema>;
export type SimFeaturesUpdateRequest = z.infer<typeof simFeaturesUpdateRequestSchema>;