import { Injectable, Inject, BadRequestException } from "@nestjs/common"; import { Logger } from "nestjs-pino"; import { extractErrorMessage } from "@bff/core/utils/error.util.js"; import { FreebitClientService } from "./freebit-client.service.js"; import { FreebitAuthService } from "./freebit-auth.service.js"; import type { FreebitEsimReissueRequest, FreebitEsimReissueResponse, FreebitEsimAddAccountRequest, FreebitEsimAddAccountResponse, FreebitEsimAccountActivationRequest, FreebitEsimAccountActivationResponse, } from "../interfaces/freebit.types.js"; export interface EsimActivationParams { account: string; eid: string; planCode?: string; contractLine?: "4G" | "5G"; aladinOperated?: "10" | "20"; shipDate?: string; addKind?: "N" | "M" | "R"; // N:新規, M:MNP転入, R:再発行 simKind?: "E0" | "E2" | "E3"; // E0:音声あり, E2:SMSなし, E3:SMSあり repAccount?: string; deliveryCode?: string; globalIp?: "10" | "20"; mnp?: { reserveNumber: string; reserveExpireDate?: string }; identity?: { firstnameKanji?: string; lastnameKanji?: string; firstnameZenKana?: string; lastnameZenKana?: string; gender?: string; birthday?: string; }; } /** * Service for Freebit eSIM operations. * Handles eSIM profile reissue and activation. */ @Injectable() export class FreebitEsimService { constructor( private readonly client: FreebitClientService, private readonly auth: FreebitAuthService, @Inject(Logger) private readonly logger: Logger ) {} /** * Reissue eSIM profile (simple version) */ async reissueEsimProfile(account: string): Promise { try { const request: Omit = { requestDatas: [{ kind: "MVNO", account }], }; await this.client.makeAuthenticatedRequest( "/mvno/reissueEsim/", request ); this.logger.log(`Successfully reissued eSIM profile for account ${account}`); } catch (error) { const message = extractErrorMessage(error); this.logger.error(`Failed to reissue eSIM profile for account ${account}`, { account, error: message, }); throw new BadRequestException(`Failed to reissue eSIM profile: ${message}`); } } /** * Reissue eSIM profile with enhanced options */ async reissueEsimProfileEnhanced( account: string, newEid: string, options: { oldProductNumber?: string; oldEid?: string; planCode?: string } = {} ): Promise { try { const request: Omit = { aladinOperated: "20", account, eid: newEid, addKind: "R", planCode: options.planCode, }; await this.client.makeAuthenticatedRequest( "/mvno/esim/addAcnt/", request ); this.logger.log(`Successfully reissued eSIM profile via addAcnt for account ${account}`, { account, newEid, oldProductNumber: options.oldProductNumber, oldEid: options.oldEid, }); } catch (error) { const message = extractErrorMessage(error); this.logger.error(`Failed to reissue eSIM profile via addAcnt for account ${account}`, { account, newEid, error: message, }); throw new BadRequestException(`Failed to reissue eSIM profile: ${message}`); } } /** * Activate new eSIM account using PA05-41 (addAcct) */ async activateEsimAccountNew(params: EsimActivationParams): Promise { const { account, eid, planCode, contractLine, aladinOperated = "10", shipDate, addKind, simKind, repAccount, deliveryCode, globalIp, mnp, identity, } = params; if (!account || !eid) { throw new BadRequestException("activateEsimAccountNew requires account and eid"); } const finalAddKind = addKind || "N"; // Validate simKind: Required except when addKind is 'R' (reissue) if (finalAddKind !== "R" && !simKind) { throw new BadRequestException( "simKind is required for eSIM activation (use 'E0' for voice, 'E3' for SMS, 'E2' for data-only)" ); } try { const payload: FreebitEsimAccountActivationRequest = { authKey: await this.auth.getAuthKey(), aladinOperated, createType: "new", eid, account, simkind: simKind || "E0", addKind: finalAddKind, planCode, contractLine, shipDate, repAccount, deliveryCode, globalIp, ...(mnp ? { mnp } : {}), ...(identity ? identity : {}), } as FreebitEsimAccountActivationRequest; await this.client.makeAuthenticatedJsonRequest< FreebitEsimAccountActivationResponse, FreebitEsimAccountActivationRequest >("/mvno/esim/addAcct/", payload); this.logger.log("Successfully activated new eSIM account via PA05-41", { account, planCode, contractLine, addKind: addKind || "N", scheduled: !!shipDate, mnp: !!mnp, }); } catch (error) { const message = extractErrorMessage(error); this.logger.error(`Failed to activate new eSIM account ${account}`, { account, eid, planCode, addKind, error: message, }); throw new BadRequestException(`Failed to activate new eSIM account: ${message}`); } } }