From 927d1c7dcf1b220b965787e2fd1664efa68ec805 Mon Sep 17 00:00:00 2001 From: tema Date: Tue, 9 Sep 2025 17:22:53 +0900 Subject: [PATCH] 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. --- .../subscriptions/sim-management.service.ts | 17 ++++++++++--- .../src/vendors/freebit/freebit.service.ts | 24 ++++++++++--------- .../freebit/interfaces/freebit.types.ts | 16 +++++++++++++ 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/apps/bff/src/subscriptions/sim-management.service.ts b/apps/bff/src/subscriptions/sim-management.service.ts index c562f33b..9628c673 100644 --- a/apps/bff/src/subscriptions/sim-management.service.ts +++ b/apps/bff/src/subscriptions/sim-management.service.ts @@ -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}`, { diff --git a/apps/bff/src/vendors/freebit/freebit.service.ts b/apps/bff/src/vendors/freebit/freebit.service.ts index 2819e7e6..6ddd7ddc 100644 --- a/apps/bff/src/vendors/freebit/freebit.service.ts +++ b/apps/bff/src/vendors/freebit/freebit.service.ts @@ -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 { try { - const request: Omit = { + const req: Omit = { + kind: 'MVNO', account, - runTime: scheduledAt, + runDate: scheduledAt, }; - - await this.makeAuthenticatedRequest( - "/mvno/releasePlan/", - request + await this.makeAuthenticatedRequest( + '/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; } } diff --git a/apps/bff/src/vendors/freebit/interfaces/freebit.types.ts b/apps/bff/src/vendors/freebit/interfaces/freebit.types.ts index 513cbb35..ead0dd4f 100644 --- a/apps/bff/src/vendors/freebit/interfaces/freebit.types.ts +++ b/apps/bff/src/vendors/freebit/interfaces/freebit.types.ts @@ -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;