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 { try {
const { account } = await this.validateSimSubscription(userId, subscriptionId); const { account } = await this.validateSimSubscription(userId, subscriptionId);
// Validate scheduled date if provided // Determine run date (PA02-04 requires runDate); default to 1st of next month
if (request.scheduledAt && !/^\d{8}$/.test(request.scheduledAt)) { let runDate = request.scheduledAt;
if (runDate && !/^\d{8}$/.test(runDate)) {
throw new BadRequestException("Scheduled date must be in YYYYMMDD format"); 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}`, { this.logger.log(`Successfully cancelled SIM for subscription ${subscriptionId}`, {
userId, userId,
subscriptionId, subscriptionId,
account, account,
runDate,
}); });
} catch (error) { } catch (error) {
this.logger.error(`Failed to cancel SIM for subscription ${subscriptionId}`, { 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> { async cancelSim(account: string, scheduledAt?: string): Promise<void> {
try { try {
const request: Omit<FreebititCancelPlanRequest, "authKey"> = { const req: Omit<import('./interfaces/freebit.types').FreebititCancelAccountRequest, 'authKey'> = {
kind: 'MVNO',
account, account,
runTime: scheduledAt, runDate: scheduledAt,
}; };
await this.makeAuthenticatedRequest<import('./interfaces/freebit.types').FreebititCancelAccountResponse>(
await this.makeAuthenticatedRequest<FreebititCancelPlanResponse>( '/master/cnclAcnt/',
"/mvno/releasePlan/", req
request
); );
this.logger.log(`Successfully requested cancellation (PA02-04) for account ${account}`, {
this.logger.log(`Successfully cancelled SIM for account ${account}`, {
account, account,
scheduled: !!scheduledAt, runDate: scheduledAt,
}); });
} catch (error: unknown) { } catch (error: unknown) {
const message = error instanceof Error ? error.message : String(error); 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; 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 { export interface FreebititEsimReissueRequest {
authKey: string; authKey: string;
account: string; account: string;