EID input now strips non-numeric characters, shows a digit counter warning while typing, and enforces exactly 32 digits via Zod schemas across domain, order configurations, and order selections layers. Also installs missing input-otp dependency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
625 lines
21 KiB
TypeScript
625 lines
21 KiB
TypeScript
/**
|
|
* SIM Domain - Schemas
|
|
*/
|
|
|
|
import { z } from "zod";
|
|
import { simCatalogProductSchema } from "../services/schema.js";
|
|
|
|
// ============================================================================
|
|
// Validation Constants
|
|
// ============================================================================
|
|
|
|
const YYYYMMDD_REGEX = /^\d{8}$/;
|
|
const MSG_SCHEDULED_DATE_FORMAT = "Scheduled date must be in YYYYMMDD format";
|
|
const EID_REGEX = /^\d{32}$/;
|
|
const MSG_EID_FORMAT = "EID must be exactly 32 digits";
|
|
|
|
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(),
|
|
startDate: z.string().optional(),
|
|
// Optional network/connectivity fields
|
|
ipv4: z.string().optional(),
|
|
ipv6: z.string().optional(),
|
|
// Optional capability flags
|
|
hasVoice: z.boolean().optional(),
|
|
hasSms: z.boolean().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),
|
|
});
|
|
|
|
/**
|
|
* Combined SIM info payload (details + usage)
|
|
*/
|
|
export const simInfoSchema = z.object({
|
|
details: simDetailsSchema,
|
|
usage: simUsageSchema,
|
|
});
|
|
|
|
// ============================================================================
|
|
// 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"),
|
|
});
|
|
|
|
/**
|
|
* Schema for SIM top-up pricing information
|
|
*/
|
|
export const simTopUpPricingSchema = z.object({
|
|
pricePerGbJpy: z.number().positive("Price per GB must be positive"),
|
|
minQuotaMb: z.number().int().positive("Minimum quota must be positive"),
|
|
maxQuotaMb: z.number().int().positive("Maximum quota must be positive"),
|
|
currency: z.string().default("JPY"),
|
|
});
|
|
|
|
export type SimTopUpPricing = z.infer<typeof simTopUpPricingSchema>;
|
|
|
|
/**
|
|
* Schema for top-up pricing preview request
|
|
*/
|
|
export const simTopUpPricingPreviewRequestSchema = z.object({
|
|
quotaMb: z.number().int().positive("Quota must be positive"),
|
|
});
|
|
|
|
export type SimTopUpPricingPreviewRequest = z.infer<typeof simTopUpPricingPreviewRequestSchema>;
|
|
|
|
/**
|
|
* Schema for top-up pricing preview response
|
|
*/
|
|
export const simTopUpPricingPreviewResponseSchema = z.object({
|
|
quotaMb: z.number(),
|
|
quotaGb: z.number(),
|
|
totalPriceJpy: z.number(),
|
|
pricePerGbJpy: z.number(),
|
|
currency: z.string(),
|
|
});
|
|
|
|
export type SimTopUpPricingPreviewResponse = z.infer<typeof simTopUpPricingPreviewResponseSchema>;
|
|
|
|
export const simPlanChangeRequestSchema = z.object({
|
|
newPlanCode: z.string().min(1, "New plan code is required"),
|
|
assignGlobalIp: z.boolean().optional(),
|
|
scheduledAt: z.string().regex(YYYYMMDD_REGEX, MSG_SCHEDULED_DATE_FORMAT).optional(),
|
|
});
|
|
|
|
export const simCancelRequestSchema = z.object({
|
|
scheduledAt: z.string().regex(YYYYMMDD_REGEX, MSG_SCHEDULED_DATE_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(),
|
|
});
|
|
|
|
export const simReissueRequestSchema = z.object({
|
|
newEid: z.string().regex(EID_REGEX, MSG_EID_FORMAT).optional(),
|
|
simType: z.enum(["physical", "esim"]).optional(),
|
|
});
|
|
|
|
// ============================================================================
|
|
// Portal-facing SIM DTOs (responses + request contracts)
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Available plan for SIM plan change (portal-facing)
|
|
*
|
|
* This extends the catalog's SIM product shape with:
|
|
* - freebitPlanCode: the actual plan code used by Freebit
|
|
* - isCurrentPlan: whether this is the customer's current plan
|
|
*/
|
|
export const simAvailablePlanSchema = simCatalogProductSchema.extend({
|
|
freebitPlanCode: z.string(),
|
|
isCurrentPlan: z.boolean(),
|
|
});
|
|
|
|
export type SimAvailablePlan = z.infer<typeof simAvailablePlanSchema>;
|
|
|
|
export const simAvailablePlanArraySchema = z.array(simAvailablePlanSchema);
|
|
export type SimAvailablePlanArray = z.infer<typeof simAvailablePlanArraySchema>;
|
|
|
|
/**
|
|
* Cancellation month option for SIM cancellation preview
|
|
*/
|
|
export const simCancellationMonthSchema = z.object({
|
|
value: z.string().regex(/^\d{4}-\d{2}$/, "Month must be in YYYY-MM format"),
|
|
label: z.string(),
|
|
runDate: z.string().regex(/^\d{8}$/, "runDate must be in YYYYMMDD format"),
|
|
});
|
|
|
|
export type SimCancellationMonth = z.infer<typeof simCancellationMonthSchema>;
|
|
|
|
/**
|
|
* SIM cancellation preview payload (portal-facing)
|
|
*/
|
|
export const simCancellationPreviewSchema = z.object({
|
|
simNumber: z.string(),
|
|
serialNumber: z.string().optional(),
|
|
planCode: z.string(),
|
|
startDate: z.string().optional(),
|
|
minimumContractEndDate: z.string().optional(),
|
|
isWithinMinimumTerm: z.boolean(),
|
|
availableMonths: z.array(simCancellationMonthSchema),
|
|
customerEmail: z.string(),
|
|
customerName: z.string(),
|
|
});
|
|
|
|
export type SimCancellationPreview = z.infer<typeof simCancellationPreviewSchema>;
|
|
|
|
/**
|
|
* Reissue SIM request (full flow) for `/api/subscriptions/:id/sim/reissue`
|
|
*
|
|
* - Physical SIM: simType="physical" (newEid optional/ignored)
|
|
* - eSIM: simType="esim" and newEid is required
|
|
*/
|
|
export const simReissueFullRequestSchema = z
|
|
.object({
|
|
simType: z.enum(["physical", "esim"]),
|
|
newEid: z.string().regex(EID_REGEX, MSG_EID_FORMAT).optional(),
|
|
})
|
|
.superRefine((data, ctx) => {
|
|
if (data.simType === "esim" && !data.newEid) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
message: "newEid is required for eSIM reissue",
|
|
path: ["newEid"],
|
|
});
|
|
}
|
|
});
|
|
|
|
export type SimReissueFullRequest = z.infer<typeof simReissueFullRequestSchema>;
|
|
|
|
// ============================================================================
|
|
// SIM Call/SMS History (portal-facing)
|
|
// ============================================================================
|
|
|
|
export const simHistoryMonthSchema = z
|
|
.string()
|
|
.regex(/^\d{4}-\d{2}$/, "Month must be in YYYY-MM format");
|
|
export type SimHistoryMonth = z.infer<typeof simHistoryMonthSchema>;
|
|
|
|
export const simHistoryAvailableMonthsSchema = z.array(simHistoryMonthSchema);
|
|
export type SimHistoryAvailableMonths = z.infer<typeof simHistoryAvailableMonthsSchema>;
|
|
|
|
export const simCallHistoryImportResultSchema = z.object({
|
|
domestic: z.number().int().min(0),
|
|
international: z.number().int().min(0),
|
|
sms: z.number().int().min(0),
|
|
});
|
|
export type SimCallHistoryImportResult = z.infer<typeof simCallHistoryImportResultSchema>;
|
|
|
|
export const simSftpFilesSchema = z.array(z.string());
|
|
export type SimSftpFiles = z.infer<typeof simSftpFilesSchema>;
|
|
|
|
export const simSftpListResultSchema = z.object({
|
|
path: z.string(),
|
|
files: simSftpFilesSchema,
|
|
});
|
|
export type SimSftpListResult = z.infer<typeof simSftpListResultSchema>;
|
|
|
|
const isoDateSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in YYYY-MM-DD format");
|
|
const timeHmsSchema = z.string().regex(/^\d{2}:\d{2}:\d{2}$/, "Time must be in HH:MM:SS format");
|
|
|
|
export const simCallHistoryPaginationSchema = z.object({
|
|
page: z.number().int().min(1),
|
|
limit: z.number().int().min(1),
|
|
total: z.number().int().min(0),
|
|
totalPages: z.number().int().min(0),
|
|
});
|
|
|
|
export type SimCallHistoryPagination = z.infer<typeof simCallHistoryPaginationSchema>;
|
|
|
|
export const simDomesticCallRecordSchema = z.object({
|
|
id: z.string(),
|
|
date: isoDateSchema,
|
|
time: timeHmsSchema,
|
|
calledTo: z.string(),
|
|
callLength: z.string(),
|
|
callCharge: z.number(),
|
|
});
|
|
|
|
export type SimDomesticCallRecord = z.infer<typeof simDomesticCallRecordSchema>;
|
|
|
|
export const simDomesticCallHistoryResponseSchema = z.object({
|
|
calls: z.array(simDomesticCallRecordSchema),
|
|
pagination: simCallHistoryPaginationSchema,
|
|
month: simHistoryMonthSchema,
|
|
});
|
|
|
|
export type SimDomesticCallHistoryResponse = z.infer<typeof simDomesticCallHistoryResponseSchema>;
|
|
|
|
export const simInternationalCallRecordSchema = z.object({
|
|
id: z.string(),
|
|
date: isoDateSchema,
|
|
startTime: timeHmsSchema,
|
|
stopTime: z.string().nullable(),
|
|
country: z.string().nullable(),
|
|
calledTo: z.string(),
|
|
callCharge: z.number(),
|
|
});
|
|
|
|
export type SimInternationalCallRecord = z.infer<typeof simInternationalCallRecordSchema>;
|
|
|
|
export const simInternationalCallHistoryResponseSchema = z.object({
|
|
calls: z.array(simInternationalCallRecordSchema),
|
|
pagination: simCallHistoryPaginationSchema,
|
|
month: simHistoryMonthSchema,
|
|
});
|
|
|
|
export type SimInternationalCallHistoryResponse = z.infer<
|
|
typeof simInternationalCallHistoryResponseSchema
|
|
>;
|
|
|
|
/**
|
|
* Schema for SIM history query parameters (pagination + month)
|
|
*/
|
|
export const simHistoryQuerySchema = z.object({
|
|
month: simHistoryMonthSchema.optional(),
|
|
page: z.coerce.number().int().min(1).optional().default(1),
|
|
limit: z.coerce.number().int().min(1).max(100).optional().default(50),
|
|
});
|
|
|
|
export type SimHistoryQuery = z.infer<typeof simHistoryQuerySchema>;
|
|
|
|
/**
|
|
* Schema for SFTP file listing query
|
|
*/
|
|
export const simSftpListQuerySchema = z.object({
|
|
path: z.string().startsWith("/home/PASI", "Invalid path").default("/home/PASI"),
|
|
});
|
|
|
|
export type SimSftpListQuery = z.infer<typeof simSftpListQuerySchema>;
|
|
|
|
/**
|
|
* Schema for call history import query
|
|
*/
|
|
export const simCallHistoryImportQuerySchema = z.object({
|
|
month: z.string().regex(/^\d{6}$/, "Invalid month format (expected YYYYMM)"),
|
|
});
|
|
|
|
export type SimCallHistoryImportQuery = z.infer<typeof simCallHistoryImportQuerySchema>;
|
|
|
|
/**
|
|
* Schema for SIM eSIM reissue request
|
|
*/
|
|
export const simReissueEsimRequestSchema = z.object({
|
|
newEid: z.string().regex(EID_REGEX, MSG_EID_FORMAT).optional(),
|
|
});
|
|
|
|
export type SimReissueEsimRequest = z.infer<typeof simReissueEsimRequestSchema>;
|
|
|
|
export const simSmsRecordSchema = z.object({
|
|
id: z.string(),
|
|
date: isoDateSchema,
|
|
time: timeHmsSchema,
|
|
sentTo: z.string(),
|
|
type: z.string(),
|
|
});
|
|
|
|
export type SimSmsRecord = z.infer<typeof simSmsRecordSchema>;
|
|
|
|
export const simSmsHistoryResponseSchema = z.object({
|
|
messages: z.array(simSmsRecordSchema),
|
|
pagination: simCallHistoryPaginationSchema,
|
|
month: simHistoryMonthSchema,
|
|
});
|
|
|
|
export type SimSmsHistoryResponse = z.infer<typeof simSmsHistoryResponseSchema>;
|
|
|
|
// Enhanced cancellation request with more details
|
|
export const simCancelFullRequestSchema = z
|
|
.object({
|
|
cancellationMonth: z
|
|
.string()
|
|
.regex(/^\d{4}-\d{2}$/, "Cancellation month must be in YYYY-MM format"),
|
|
confirmRead: z.boolean(),
|
|
confirmCancel: z.boolean(),
|
|
comments: z.string().max(1000).optional(),
|
|
})
|
|
.refine(data => data.confirmRead === true && data.confirmCancel === true, {
|
|
message: "You must confirm both checkboxes to proceed",
|
|
});
|
|
|
|
// Top-up request with enhanced details for email
|
|
export const simTopUpFullRequestSchema = z.object({
|
|
quotaMb: z
|
|
.number()
|
|
.int()
|
|
.min(100, "Quota must be at least 100MB")
|
|
.max(51200, "Quota must be 50GB or less"),
|
|
});
|
|
|
|
// Change plan request with Salesforce product info
|
|
export const simChangePlanFullRequestSchema = z.object({
|
|
newPlanCode: z.string().min(1, "New plan code is required"),
|
|
newPlanSku: z.string().min(1, "New plan SKU is required"),
|
|
newPlanName: z.string().optional(),
|
|
assignGlobalIp: z.boolean().optional(),
|
|
});
|
|
|
|
const simMnpFormSchema = z.object({
|
|
reservationNumber: z.string().min(1, "Reservation number is required"),
|
|
expiryDate: z.string().regex(/^\d{8}$/, "Expiry date must be in YYYYMMDD format"),
|
|
phoneNumber: z
|
|
.string()
|
|
.min(1, "Phone number is required")
|
|
.max(11, "Phone number must be 11 digits or fewer"),
|
|
mvnoAccountNumber: z.string().optional(),
|
|
portingLastName: z.string().optional(),
|
|
portingFirstName: z.string().optional(),
|
|
portingLastNameKatakana: z.string().optional(),
|
|
portingFirstNameKatakana: z.string().optional(),
|
|
portingGender: z.string().optional(),
|
|
portingDateOfBirth: z
|
|
.string()
|
|
.regex(/^\d{8}$/, "Birthday must be in YYYYMMDD format")
|
|
.optional(),
|
|
});
|
|
|
|
export const simCardTypeSchema = z.enum(["eSIM", "Physical SIM"]);
|
|
|
|
export const simActivationTypeSchema = z.enum(["Immediate", "Scheduled"]);
|
|
|
|
export const simConfigureFormSchema = z
|
|
.object({
|
|
simType: simCardTypeSchema,
|
|
eid: z
|
|
.string()
|
|
.regex(/^\d{32}$/, "EID must be exactly 32 digits")
|
|
.optional(),
|
|
selectedAddons: z.array(z.string()).default([]),
|
|
activationType: simActivationTypeSchema,
|
|
scheduledActivationDate: z.string().regex(YYYYMMDD_REGEX, MSG_SCHEDULED_DATE_FORMAT).optional(),
|
|
wantsMnp: z.boolean().default(false),
|
|
mnpData: simMnpFormSchema.optional(),
|
|
})
|
|
.superRefine((data, ctx) => {
|
|
if (data.simType === "eSIM" && (!data.eid || !/^\d{32}$/.test(data.eid.trim()))) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
path: ["eid"],
|
|
message: "EID must be exactly 32 digits",
|
|
});
|
|
}
|
|
|
|
if (data.activationType === "Scheduled" && !data.scheduledActivationDate) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
path: ["scheduledActivationDate"],
|
|
message: "Scheduled activation date is required when activation type is Scheduled",
|
|
});
|
|
}
|
|
|
|
if (data.wantsMnp) {
|
|
if (!data.mnpData) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
path: ["mnpData"],
|
|
message: "MNP data is required when porting is selected",
|
|
});
|
|
return;
|
|
}
|
|
|
|
const { reservationNumber, expiryDate, phoneNumber } = data.mnpData;
|
|
if (!reservationNumber) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
path: ["mnpData", "reservationNumber"],
|
|
message: "Reservation number is required",
|
|
});
|
|
}
|
|
if (!expiryDate) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
path: ["mnpData", "expiryDate"],
|
|
message: "Reservation expiry date is required",
|
|
});
|
|
}
|
|
if (!phoneNumber) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
path: ["mnpData", "phoneNumber"],
|
|
message: "Phone number is required for porting",
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
// ============================================================================
|
|
// 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: simCardTypeSchema,
|
|
eid: z
|
|
.string()
|
|
.regex(/^\d{32}$/, "EID must be exactly 32 digits")
|
|
.optional(),
|
|
activationType: simActivationTypeSchema,
|
|
scheduledAt: z.string().regex(YYYYMMDD_REGEX, MSG_SCHEDULED_DATE_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
|
|
return !(data.simType === "eSIM" && (!data.eid || data.eid.length < 15));
|
|
},
|
|
{
|
|
message: "EID is required for eSIM and must be at least 15 characters",
|
|
path: ["eid"],
|
|
}
|
|
)
|
|
.refine(
|
|
data => {
|
|
// If activationType is Scheduled, scheduledAt is required
|
|
return !(data.activationType === "Scheduled" && !data.scheduledAt);
|
|
},
|
|
{
|
|
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>;
|
|
|
|
// ============================================================================
|
|
// 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>;
|
|
export type SimInfo = z.infer<typeof simInfoSchema>;
|
|
|
|
// 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>;
|
|
export type SimReissueRequest = z.infer<typeof simReissueRequestSchema>;
|
|
export type SimCancelFullRequest = z.infer<typeof simCancelFullRequestSchema>;
|
|
export type SimTopUpFullRequest = z.infer<typeof simTopUpFullRequestSchema>;
|
|
export type SimChangePlanFullRequest = z.infer<typeof simChangePlanFullRequestSchema>;
|
|
export type SimConfigureFormData = z.infer<typeof simConfigureFormSchema>;
|
|
export type SimCardType = z.infer<typeof simCardTypeSchema>;
|
|
export type ActivationType = z.infer<typeof simActivationTypeSchema>;
|
|
export type MnpData = z.infer<typeof simMnpFormSchema>;
|
|
|
|
export interface SimConfigureFormToRequestOptions {
|
|
planSku: string;
|
|
msisdn: string;
|
|
monthlyAmountJpy: number;
|
|
oneTimeAmountJpy: number;
|
|
addons?: SimOrderActivationAddons;
|
|
}
|
|
|
|
export function simConfigureFormToRequest(
|
|
formData: SimConfigureFormData,
|
|
options: SimConfigureFormToRequestOptions
|
|
): SimOrderActivationRequest {
|
|
const scheduledAt =
|
|
formData.activationType === "Scheduled" ? formData.scheduledActivationDate : undefined;
|
|
|
|
const mnp =
|
|
formData.wantsMnp && formData.mnpData
|
|
? {
|
|
reserveNumber: formData.mnpData.reservationNumber,
|
|
reserveExpireDate: formData.mnpData.expiryDate,
|
|
account: formData.mnpData.mvnoAccountNumber ?? undefined,
|
|
firstnameKanji: formData.mnpData.portingFirstName ?? undefined,
|
|
lastnameKanji: formData.mnpData.portingLastName ?? undefined,
|
|
firstnameZenKana: formData.mnpData.portingFirstNameKatakana ?? undefined,
|
|
lastnameZenKana: formData.mnpData.portingLastNameKatakana ?? undefined,
|
|
gender: formData.mnpData.portingGender ?? undefined,
|
|
birthday: formData.mnpData.portingDateOfBirth ?? undefined,
|
|
}
|
|
: undefined;
|
|
|
|
return simOrderActivationRequestSchema.parse({
|
|
planSku: options.planSku,
|
|
simType: formData.simType,
|
|
eid: formData.simType === "eSIM" ? formData.eid?.trim() || undefined : undefined,
|
|
activationType: formData.activationType,
|
|
scheduledAt,
|
|
addons: options.addons,
|
|
mnp,
|
|
msisdn: options.msisdn,
|
|
oneTimeAmountJpy: options.oneTimeAmountJpy,
|
|
monthlyAmountJpy: options.monthlyAmountJpy,
|
|
});
|
|
}
|