Refactor SIM cancellation logic and Freebit service integration for improved scheduling and error handling

- Updated SimManagementService to determine the run date for SIM cancellations, defaulting to the 1st of the next month if no date is provided.
- Modified FreebititService to align with the new cancellation request structure, utilizing the PA02-04 API for account cancellations.
- Enhanced logging to provide clearer information regarding cancellation requests and their statuses.
This commit is contained in:
tema 2025-09-09 17:22:53 +09:00
parent 74e27e3ca2
commit 927d1c7dcf
3 changed files with 43 additions and 14 deletions

View File

@ -715,17 +715,28 @@ export class SimManagementService {
try {
const { account } = await this.validateSimSubscription(userId, subscriptionId);
// Validate scheduled date if provided
if (request.scheduledAt && !/^\d{8}$/.test(request.scheduledAt)) {
// Determine run date (PA02-04 requires runDate); default to 1st of next month
let runDate = request.scheduledAt;
if (runDate && !/^\d{8}$/.test(runDate)) {
throw new BadRequestException("Scheduled date must be in YYYYMMDD format");
}
if (!runDate) {
const nextMonth = new Date();
nextMonth.setMonth(nextMonth.getMonth() + 1);
nextMonth.setDate(1);
const y = nextMonth.getFullYear();
const m = String(nextMonth.getMonth() + 1).padStart(2, '0');
const d = String(nextMonth.getDate()).padStart(2, '0');
runDate = `${y}${m}${d}`;
}
await this.freebititService.cancelSim(account, request.scheduledAt);
await this.freebititService.cancelSim(account, runDate);
this.logger.log(`Successfully cancelled SIM for subscription ${subscriptionId}`, {
userId,
subscriptionId,
account,
runDate,
});
} catch (error) {
this.logger.error(`Failed to cancel SIM for subscription ${subscriptionId}`, {

View File

@ -702,27 +702,29 @@ export class FreebititService {
}
/**
* Cancel SIM service
* Cancel SIM service via PA02-04 (master/cnclAcnt)
*/
async cancelSim(account: string, scheduledAt?: string): Promise<void> {
try {
const request: Omit<FreebititCancelPlanRequest, "authKey"> = {
const req: Omit<import('./interfaces/freebit.types').FreebititCancelAccountRequest, 'authKey'> = {
kind: 'MVNO',
account,
runTime: scheduledAt,
runDate: scheduledAt,
};
await this.makeAuthenticatedRequest<FreebititCancelPlanResponse>(
"/mvno/releasePlan/",
request
await this.makeAuthenticatedRequest<import('./interfaces/freebit.types').FreebititCancelAccountResponse>(
'/master/cnclAcnt/',
req
);
this.logger.log(`Successfully cancelled SIM for account ${account}`, {
this.logger.log(`Successfully requested cancellation (PA02-04) for account ${account}`, {
account,
scheduled: !!scheduledAt,
runDate: scheduledAt,
});
} catch (error: unknown) {
const message = error instanceof Error ? error.message : String(error);
this.logger.error(`Failed to cancel SIM for account ${account}`, { error: message, account });
this.logger.error(`Failed to request cancellation (PA02-04) for account ${account}`, {
error: message,
account,
});
throw error as Error;
}
}

View File

@ -243,6 +243,22 @@ export interface FreebititCancelPlanResponse {
};
}
// PA02-04: Account Cancellation (master/cnclAcnt)
export interface FreebititCancelAccountRequest {
authKey: string;
kind: string; // e.g., 'MVNO'
account: string;
runDate?: string; // YYYYMMDD
}
export interface FreebititCancelAccountResponse {
resultCode: string;
status: {
message: string;
statusCode: string;
};
}
export interface FreebititEsimReissueRequest {
authKey: string;
account: string;