2025-08-22 17:02:49 +09:00
|
|
|
import {
|
|
|
|
|
Controller,
|
|
|
|
|
Get,
|
2025-09-04 18:34:28 +09:00
|
|
|
Post,
|
2025-08-22 17:02:49 +09:00
|
|
|
Param,
|
|
|
|
|
Query,
|
2025-09-04 18:34:28 +09:00
|
|
|
Body,
|
2025-08-20 18:02:50 +09:00
|
|
|
Request,
|
|
|
|
|
ParseIntPipe,
|
|
|
|
|
BadRequestException,
|
2025-08-22 17:02:49 +09:00
|
|
|
} from "@nestjs/common";
|
|
|
|
|
import {
|
|
|
|
|
ApiTags,
|
|
|
|
|
ApiOperation,
|
|
|
|
|
ApiResponse,
|
|
|
|
|
ApiQuery,
|
2025-08-20 18:02:50 +09:00
|
|
|
ApiBearerAuth,
|
|
|
|
|
ApiParam,
|
2025-09-04 18:34:28 +09:00
|
|
|
ApiBody,
|
2025-08-22 17:02:49 +09:00
|
|
|
} from "@nestjs/swagger";
|
|
|
|
|
import { SubscriptionsService } from "./subscriptions.service";
|
2025-09-04 18:34:28 +09:00
|
|
|
import { SimManagementService } from "./sim-management.service";
|
2025-08-28 16:57:57 +09:00
|
|
|
|
2025-08-22 17:02:49 +09:00
|
|
|
import { Subscription, SubscriptionList, InvoiceList } from "@customer-portal/shared";
|
2025-09-01 15:11:42 +09:00
|
|
|
import type { RequestWithUser } from "../auth/auth.types";
|
2025-08-20 18:02:50 +09:00
|
|
|
|
2025-08-22 17:02:49 +09:00
|
|
|
@ApiTags("subscriptions")
|
|
|
|
|
@Controller("subscriptions")
|
2025-08-20 18:02:50 +09:00
|
|
|
@ApiBearerAuth()
|
|
|
|
|
export class SubscriptionsController {
|
2025-09-04 18:34:28 +09:00
|
|
|
constructor(
|
|
|
|
|
private readonly subscriptionsService: SubscriptionsService,
|
|
|
|
|
private readonly simManagementService: SimManagementService,
|
|
|
|
|
) {}
|
2025-08-20 18:02:50 +09:00
|
|
|
|
|
|
|
|
@Get()
|
2025-08-22 17:02:49 +09:00
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Get all user subscriptions",
|
|
|
|
|
description: "Retrieves all subscriptions/services for the authenticated user",
|
2025-08-20 18:02:50 +09:00
|
|
|
})
|
2025-08-22 17:02:49 +09:00
|
|
|
@ApiQuery({
|
|
|
|
|
name: "status",
|
|
|
|
|
required: false,
|
|
|
|
|
type: String,
|
|
|
|
|
description: "Filter by subscription status",
|
|
|
|
|
})
|
|
|
|
|
@ApiResponse({
|
|
|
|
|
status: 200,
|
|
|
|
|
description: "List of user subscriptions",
|
2025-08-20 18:02:50 +09:00
|
|
|
type: Object, // Would be SubscriptionList if we had proper DTO decorators
|
|
|
|
|
})
|
|
|
|
|
async getSubscriptions(
|
2025-08-23 17:24:37 +09:00
|
|
|
@Request() req: RequestWithUser,
|
2025-08-22 17:02:49 +09:00
|
|
|
@Query("status") status?: string
|
2025-08-20 18:02:50 +09:00
|
|
|
): Promise<SubscriptionList | Subscription[]> {
|
|
|
|
|
// Validate status if provided
|
2025-08-22 17:02:49 +09:00
|
|
|
if (status && !["Active", "Suspended", "Terminated", "Cancelled", "Pending"].includes(status)) {
|
|
|
|
|
throw new BadRequestException("Invalid status filter");
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (status) {
|
2025-08-22 17:02:49 +09:00
|
|
|
const subscriptions = await this.subscriptionsService.getSubscriptionsByStatus(
|
2025-08-27 10:54:05 +09:00
|
|
|
req.user.id,
|
2025-08-22 17:02:49 +09:00
|
|
|
status
|
|
|
|
|
);
|
2025-08-20 18:02:50 +09:00
|
|
|
return subscriptions;
|
|
|
|
|
}
|
2025-08-22 17:02:49 +09:00
|
|
|
|
2025-08-27 10:54:05 +09:00
|
|
|
return this.subscriptionsService.getSubscriptions(req.user.id);
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|
|
|
|
|
|
2025-08-22 17:02:49 +09:00
|
|
|
@Get("active")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Get active subscriptions only",
|
|
|
|
|
description: "Retrieves only active subscriptions for the authenticated user",
|
2025-08-20 18:02:50 +09:00
|
|
|
})
|
2025-08-22 17:02:49 +09:00
|
|
|
@ApiResponse({
|
|
|
|
|
status: 200,
|
|
|
|
|
description: "List of active subscriptions",
|
2025-08-20 18:02:50 +09:00
|
|
|
type: [Object], // Would be Subscription[] if we had proper DTO decorators
|
|
|
|
|
})
|
2025-08-23 17:24:37 +09:00
|
|
|
async getActiveSubscriptions(@Request() req: RequestWithUser): Promise<Subscription[]> {
|
2025-08-27 10:54:05 +09:00
|
|
|
return this.subscriptionsService.getActiveSubscriptions(req.user.id);
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|
|
|
|
|
|
2025-08-22 17:02:49 +09:00
|
|
|
@Get("stats")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Get subscription statistics",
|
|
|
|
|
description: "Retrieves subscription count statistics by status",
|
2025-08-20 18:02:50 +09:00
|
|
|
})
|
2025-08-22 17:02:49 +09:00
|
|
|
@ApiResponse({
|
|
|
|
|
status: 200,
|
|
|
|
|
description: "Subscription statistics",
|
2025-08-20 18:02:50 +09:00
|
|
|
type: Object,
|
|
|
|
|
})
|
2025-08-23 17:24:37 +09:00
|
|
|
async getSubscriptionStats(@Request() req: RequestWithUser): Promise<{
|
2025-08-20 18:02:50 +09:00
|
|
|
total: number;
|
|
|
|
|
active: number;
|
|
|
|
|
suspended: number;
|
|
|
|
|
cancelled: number;
|
|
|
|
|
pending: number;
|
|
|
|
|
}> {
|
2025-08-27 10:54:05 +09:00
|
|
|
return this.subscriptionsService.getSubscriptionStats(req.user.id);
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|
|
|
|
|
|
2025-08-22 17:02:49 +09:00
|
|
|
@Get(":id")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Get subscription details by ID",
|
|
|
|
|
description: "Retrieves detailed information for a specific subscription",
|
2025-08-20 18:02:50 +09:00
|
|
|
})
|
2025-08-22 17:02:49 +09:00
|
|
|
@ApiParam({ name: "id", type: Number, description: "Subscription ID" })
|
|
|
|
|
@ApiResponse({
|
|
|
|
|
status: 200,
|
|
|
|
|
description: "Subscription details",
|
2025-08-20 18:02:50 +09:00
|
|
|
type: Object, // Would be Subscription if we had proper DTO decorators
|
|
|
|
|
})
|
2025-08-22 17:02:49 +09:00
|
|
|
@ApiResponse({ status: 404, description: "Subscription not found" })
|
2025-08-20 18:02:50 +09:00
|
|
|
async getSubscriptionById(
|
2025-08-23 17:24:37 +09:00
|
|
|
@Request() req: RequestWithUser,
|
2025-08-22 17:02:49 +09:00
|
|
|
@Param("id", ParseIntPipe) subscriptionId: number
|
2025-08-20 18:02:50 +09:00
|
|
|
): Promise<Subscription> {
|
|
|
|
|
if (subscriptionId <= 0) {
|
2025-08-22 17:02:49 +09:00
|
|
|
throw new BadRequestException("Subscription ID must be a positive number");
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|
2025-08-22 17:02:49 +09:00
|
|
|
|
2025-08-27 10:54:05 +09:00
|
|
|
return this.subscriptionsService.getSubscriptionById(req.user.id, subscriptionId);
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|
|
|
|
|
|
2025-08-22 17:02:49 +09:00
|
|
|
@Get(":id/invoices")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Get invoices for a specific subscription",
|
|
|
|
|
description: "Retrieves all invoices related to a specific subscription",
|
2025-08-20 18:02:50 +09:00
|
|
|
})
|
2025-08-22 17:02:49 +09:00
|
|
|
@ApiParam({ name: "id", type: Number, description: "Subscription ID" })
|
|
|
|
|
@ApiQuery({
|
|
|
|
|
name: "page",
|
|
|
|
|
required: false,
|
|
|
|
|
type: Number,
|
|
|
|
|
description: "Page number (default: 1)",
|
|
|
|
|
})
|
|
|
|
|
@ApiQuery({
|
|
|
|
|
name: "limit",
|
|
|
|
|
required: false,
|
|
|
|
|
type: Number,
|
|
|
|
|
description: "Items per page (default: 10)",
|
|
|
|
|
})
|
|
|
|
|
@ApiResponse({
|
|
|
|
|
status: 200,
|
|
|
|
|
description: "List of invoices for the subscription",
|
2025-08-20 18:02:50 +09:00
|
|
|
type: Object, // Would be InvoiceList if we had proper DTO decorators
|
|
|
|
|
})
|
2025-08-22 17:02:49 +09:00
|
|
|
@ApiResponse({ status: 404, description: "Subscription not found" })
|
2025-08-20 18:02:50 +09:00
|
|
|
async getSubscriptionInvoices(
|
2025-08-23 17:24:37 +09:00
|
|
|
@Request() req: RequestWithUser,
|
2025-08-22 17:02:49 +09:00
|
|
|
@Param("id", ParseIntPipe) subscriptionId: number,
|
|
|
|
|
@Query("page") page?: string,
|
|
|
|
|
@Query("limit") limit?: string
|
2025-08-20 18:02:50 +09:00
|
|
|
): Promise<InvoiceList> {
|
|
|
|
|
if (subscriptionId <= 0) {
|
2025-08-22 17:02:49 +09:00
|
|
|
throw new BadRequestException("Subscription ID must be a positive number");
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate and sanitize input
|
2025-08-22 17:02:49 +09:00
|
|
|
const pageNum = this.validatePositiveInteger(page, 1, "page");
|
|
|
|
|
const limitNum = this.validatePositiveInteger(limit, 10, "limit");
|
|
|
|
|
|
2025-08-20 18:02:50 +09:00
|
|
|
// Limit max page size for performance
|
|
|
|
|
if (limitNum > 100) {
|
2025-08-22 17:02:49 +09:00
|
|
|
throw new BadRequestException("Limit cannot exceed 100 items per page");
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|
2025-08-22 17:02:49 +09:00
|
|
|
|
2025-08-27 10:54:05 +09:00
|
|
|
return this.subscriptionsService.getSubscriptionInvoices(req.user.id, subscriptionId, {
|
2025-08-22 17:02:49 +09:00
|
|
|
page: pageNum,
|
|
|
|
|
limit: limitNum,
|
|
|
|
|
});
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|
|
|
|
|
|
2025-08-22 17:02:49 +09:00
|
|
|
private validatePositiveInteger(
|
|
|
|
|
value: string | undefined,
|
|
|
|
|
defaultValue: number,
|
|
|
|
|
fieldName: string
|
|
|
|
|
): number {
|
2025-08-20 18:02:50 +09:00
|
|
|
if (!value) {
|
|
|
|
|
return defaultValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const parsed = parseInt(value, 10);
|
|
|
|
|
if (isNaN(parsed) || parsed <= 0) {
|
|
|
|
|
throw new BadRequestException(`${fieldName} must be a positive integer`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return parsed;
|
|
|
|
|
}
|
2025-09-04 18:34:28 +09:00
|
|
|
|
|
|
|
|
// ==================== SIM Management Endpoints ====================
|
|
|
|
|
|
|
|
|
|
@Get(":id/sim/debug")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Debug SIM subscription data",
|
|
|
|
|
description: "Retrieves subscription data to help debug SIM management issues",
|
|
|
|
|
})
|
|
|
|
|
@ApiParam({ name: "id", type: Number, description: "Subscription ID" })
|
|
|
|
|
@ApiResponse({ status: 200, description: "Subscription debug data" })
|
|
|
|
|
async debugSimSubscription(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Param("id", ParseIntPipe) subscriptionId: number
|
|
|
|
|
) {
|
|
|
|
|
return this.simManagementService.debugSimSubscription(req.user.id, subscriptionId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Get(":id/sim")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Get SIM details and usage",
|
|
|
|
|
description: "Retrieves comprehensive SIM information including details and current usage",
|
|
|
|
|
})
|
|
|
|
|
@ApiParam({ name: "id", type: Number, description: "Subscription ID" })
|
|
|
|
|
@ApiResponse({ status: 200, description: "SIM information" })
|
|
|
|
|
@ApiResponse({ status: 400, description: "Not a SIM subscription" })
|
|
|
|
|
@ApiResponse({ status: 404, description: "Subscription not found" })
|
|
|
|
|
async getSimInfo(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Param("id", ParseIntPipe) subscriptionId: number
|
|
|
|
|
) {
|
|
|
|
|
return this.simManagementService.getSimInfo(req.user.id, subscriptionId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Get(":id/sim/details")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Get SIM details",
|
|
|
|
|
description: "Retrieves detailed SIM information including ICCID, plan, status, etc.",
|
|
|
|
|
})
|
|
|
|
|
@ApiParam({ name: "id", type: Number, description: "Subscription ID" })
|
|
|
|
|
@ApiResponse({ status: 200, description: "SIM details" })
|
|
|
|
|
async getSimDetails(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Param("id", ParseIntPipe) subscriptionId: number
|
|
|
|
|
) {
|
|
|
|
|
return this.simManagementService.getSimDetails(req.user.id, subscriptionId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Get(":id/sim/usage")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Get SIM data usage",
|
|
|
|
|
description: "Retrieves current data usage and recent usage history",
|
|
|
|
|
})
|
|
|
|
|
@ApiParam({ name: "id", type: Number, description: "Subscription ID" })
|
|
|
|
|
@ApiResponse({ status: 200, description: "SIM usage data" })
|
|
|
|
|
async getSimUsage(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Param("id", ParseIntPipe) subscriptionId: number
|
|
|
|
|
) {
|
|
|
|
|
return this.simManagementService.getSimUsage(req.user.id, subscriptionId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Get(":id/sim/top-up-history")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Get SIM top-up history",
|
|
|
|
|
description: "Retrieves data top-up history for the specified date range",
|
|
|
|
|
})
|
|
|
|
|
@ApiParam({ name: "id", type: Number, description: "Subscription ID" })
|
|
|
|
|
@ApiQuery({ name: "fromDate", description: "Start date (YYYYMMDD)", example: "20240101" })
|
|
|
|
|
@ApiQuery({ name: "toDate", description: "End date (YYYYMMDD)", example: "20241231" })
|
|
|
|
|
@ApiResponse({ status: 200, description: "Top-up history" })
|
|
|
|
|
async getSimTopUpHistory(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Param("id", ParseIntPipe) subscriptionId: number,
|
|
|
|
|
@Query("fromDate") fromDate: string,
|
|
|
|
|
@Query("toDate") toDate: string
|
|
|
|
|
) {
|
|
|
|
|
if (!fromDate || !toDate) {
|
|
|
|
|
throw new BadRequestException("fromDate and toDate are required");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.simManagementService.getSimTopUpHistory(req.user.id, subscriptionId, {
|
|
|
|
|
fromDate,
|
|
|
|
|
toDate,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Post(":id/sim/top-up")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Top up SIM data quota",
|
|
|
|
|
description: "Add data quota to the SIM service",
|
|
|
|
|
})
|
|
|
|
|
@ApiParam({ name: "id", type: Number, description: "Subscription ID" })
|
|
|
|
|
@ApiBody({
|
|
|
|
|
description: "Top-up request",
|
|
|
|
|
schema: {
|
|
|
|
|
type: "object",
|
|
|
|
|
properties: {
|
2025-09-06 13:57:18 +09:00
|
|
|
quotaMb: { type: "number", description: "Quota in MB", example: 1024 },
|
2025-09-04 18:34:28 +09:00
|
|
|
},
|
|
|
|
|
required: ["quotaMb"],
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
@ApiResponse({ status: 200, description: "Top-up successful" })
|
|
|
|
|
async topUpSim(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Param("id", ParseIntPipe) subscriptionId: number,
|
|
|
|
|
@Body() body: {
|
|
|
|
|
quotaMb: number;
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
await this.simManagementService.topUpSim(req.user.id, subscriptionId, body);
|
|
|
|
|
return { success: true, message: "SIM top-up completed successfully" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Post(":id/sim/change-plan")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Change SIM plan",
|
|
|
|
|
description: "Change the SIM service plan",
|
|
|
|
|
})
|
|
|
|
|
@ApiParam({ name: "id", type: Number, description: "Subscription ID" })
|
|
|
|
|
@ApiBody({
|
|
|
|
|
description: "Plan change request",
|
|
|
|
|
schema: {
|
|
|
|
|
type: "object",
|
|
|
|
|
properties: {
|
|
|
|
|
newPlanCode: { type: "string", description: "New plan code", example: "LTE3G_P01" },
|
|
|
|
|
assignGlobalIp: { type: "boolean", description: "Assign global IP address" },
|
|
|
|
|
scheduledAt: { type: "string", description: "Schedule for later (YYYYMMDD)", example: "20241225" },
|
|
|
|
|
},
|
|
|
|
|
required: ["newPlanCode"],
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
@ApiResponse({ status: 200, description: "Plan change successful" })
|
|
|
|
|
async changeSimPlan(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Param("id", ParseIntPipe) subscriptionId: number,
|
|
|
|
|
@Body() body: {
|
|
|
|
|
newPlanCode: string;
|
|
|
|
|
assignGlobalIp?: boolean;
|
|
|
|
|
scheduledAt?: string;
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
const result = await this.simManagementService.changeSimPlan(req.user.id, subscriptionId, body);
|
|
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
message: "SIM plan change completed successfully",
|
|
|
|
|
...result
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Post(":id/sim/cancel")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Cancel SIM service",
|
|
|
|
|
description: "Cancel the SIM service (immediate or scheduled)",
|
|
|
|
|
})
|
|
|
|
|
@ApiParam({ name: "id", type: Number, description: "Subscription ID" })
|
|
|
|
|
@ApiBody({
|
|
|
|
|
description: "Cancellation request",
|
|
|
|
|
schema: {
|
|
|
|
|
type: "object",
|
|
|
|
|
properties: {
|
|
|
|
|
scheduledAt: { type: "string", description: "Schedule cancellation (YYYYMMDD)", example: "20241231" },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
required: false,
|
|
|
|
|
})
|
|
|
|
|
@ApiResponse({ status: 200, description: "Cancellation successful" })
|
|
|
|
|
async cancelSim(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Param("id", ParseIntPipe) subscriptionId: number,
|
|
|
|
|
@Body() body: { scheduledAt?: string } = {}
|
|
|
|
|
) {
|
|
|
|
|
await this.simManagementService.cancelSim(req.user.id, subscriptionId, body);
|
|
|
|
|
return { success: true, message: "SIM cancellation completed successfully" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Post(":id/sim/reissue-esim")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Reissue eSIM profile",
|
|
|
|
|
description: "Reissue a downloadable eSIM profile (eSIM only)",
|
|
|
|
|
})
|
|
|
|
|
@ApiParam({ name: "id", type: Number, description: "Subscription ID" })
|
|
|
|
|
@ApiResponse({ status: 200, description: "eSIM reissue successful" })
|
|
|
|
|
@ApiResponse({ status: 400, description: "Not an eSIM subscription" })
|
|
|
|
|
async reissueEsimProfile(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Param("id", ParseIntPipe) subscriptionId: number
|
|
|
|
|
) {
|
|
|
|
|
await this.simManagementService.reissueEsimProfile(req.user.id, subscriptionId);
|
|
|
|
|
return { success: true, message: "eSIM profile reissue completed successfully" };
|
|
|
|
|
}
|
2025-09-05 15:39:43 +09:00
|
|
|
|
|
|
|
|
@Post(":id/sim/features")
|
|
|
|
|
@ApiOperation({
|
|
|
|
|
summary: "Update SIM features",
|
|
|
|
|
description: "Enable/disable voicemail, call waiting, international roaming, and switch network type (4G/5G)",
|
|
|
|
|
})
|
|
|
|
|
@ApiParam({ name: "id", type: Number, description: "Subscription ID" })
|
|
|
|
|
@ApiBody({
|
|
|
|
|
description: "Features update request",
|
|
|
|
|
schema: {
|
|
|
|
|
type: "object",
|
|
|
|
|
properties: {
|
|
|
|
|
voiceMailEnabled: { type: "boolean" },
|
|
|
|
|
callWaitingEnabled: { type: "boolean" },
|
|
|
|
|
internationalRoamingEnabled: { type: "boolean" },
|
|
|
|
|
networkType: { type: "string", enum: ["4G", "5G"] },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
@ApiResponse({ status: 200, description: "Features update successful" })
|
|
|
|
|
async updateSimFeatures(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Param("id", ParseIntPipe) subscriptionId: number,
|
|
|
|
|
@Body()
|
|
|
|
|
body: {
|
|
|
|
|
voiceMailEnabled?: boolean;
|
|
|
|
|
callWaitingEnabled?: boolean;
|
|
|
|
|
internationalRoamingEnabled?: boolean;
|
|
|
|
|
networkType?: '4G' | '5G';
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
await this.simManagementService.updateSimFeatures(req.user.id, subscriptionId, body);
|
|
|
|
|
return { success: true, message: "SIM features updated successfully" };
|
|
|
|
|
}
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|