2025-12-25 15:48:57 +09:00
|
|
|
import { Controller, Get, Header, Request, UseGuards } from "@nestjs/common";
|
|
|
|
|
import { RateLimitGuard, RateLimit } from "@bff/core/rate-limiting/index.js";
|
|
|
|
|
import type { RequestWithUser } from "@bff/modules/auth/auth.types.js";
|
|
|
|
|
import {
|
|
|
|
|
parseInternetCatalog,
|
|
|
|
|
parseSimCatalog,
|
|
|
|
|
parseVpnCatalog,
|
|
|
|
|
type InternetCatalogCollection,
|
|
|
|
|
type SimCatalogCollection,
|
|
|
|
|
type VpnCatalogCollection,
|
|
|
|
|
} from "@customer-portal/domain/services";
|
2026-01-13 16:19:39 +09:00
|
|
|
import { InternetServicesService } from "./application/internet-services.service.js";
|
|
|
|
|
import { SimServicesService } from "./application/sim-services.service.js";
|
|
|
|
|
import { VpnServicesService } from "./application/vpn-services.service.js";
|
2025-12-25 15:48:57 +09:00
|
|
|
import { SalesforceReadThrottleGuard } from "@bff/integrations/salesforce/guards/salesforce-read-throttle.guard.js";
|
|
|
|
|
|
2026-02-03 13:12:08 +09:00
|
|
|
const HEADER_CACHE_CONTROL = "Cache-Control";
|
|
|
|
|
const CACHE_CONTROL_PRIVATE = "private, no-store";
|
|
|
|
|
|
2025-12-25 15:48:57 +09:00
|
|
|
@Controller("account/services")
|
|
|
|
|
@UseGuards(SalesforceReadThrottleGuard, RateLimitGuard)
|
|
|
|
|
export class AccountServicesController {
|
|
|
|
|
constructor(
|
|
|
|
|
private readonly internetCatalog: InternetServicesService,
|
|
|
|
|
private readonly simCatalog: SimServicesService,
|
|
|
|
|
private readonly vpnCatalog: VpnServicesService
|
|
|
|
|
) {}
|
|
|
|
|
|
|
|
|
|
@Get("internet/plans")
|
|
|
|
|
@RateLimit({ limit: 60, ttl: 60 }) // account page refreshes are cheap; still bounded per IP+UA
|
2026-02-03 13:12:08 +09:00
|
|
|
@Header(HEADER_CACHE_CONTROL, CACHE_CONTROL_PRIVATE) // personalized
|
2025-12-25 15:48:57 +09:00
|
|
|
async getInternetCatalogForAccount(
|
|
|
|
|
@Request() req: RequestWithUser
|
|
|
|
|
): Promise<InternetCatalogCollection> {
|
|
|
|
|
const userId = req.user?.id;
|
|
|
|
|
const [plans, installations, addons] = await Promise.all([
|
|
|
|
|
this.internetCatalog.getPlansForUser(userId),
|
|
|
|
|
this.internetCatalog.getInstallations(),
|
|
|
|
|
this.internetCatalog.getAddons(),
|
|
|
|
|
]);
|
|
|
|
|
return parseInternetCatalog({ plans, installations, addons });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Get("sim/plans")
|
|
|
|
|
@RateLimit({ limit: 60, ttl: 60 })
|
2026-02-03 13:12:08 +09:00
|
|
|
@Header(HEADER_CACHE_CONTROL, CACHE_CONTROL_PRIVATE) // personalized
|
2025-12-25 15:48:57 +09:00
|
|
|
async getSimCatalogForAccount(@Request() req: RequestWithUser): Promise<SimCatalogCollection> {
|
|
|
|
|
const userId = req.user?.id;
|
|
|
|
|
const [plans, activationFees, addons] = await Promise.all([
|
|
|
|
|
this.simCatalog.getPlansForUser(userId),
|
|
|
|
|
this.simCatalog.getActivationFees(),
|
|
|
|
|
this.simCatalog.getAddons(),
|
|
|
|
|
]);
|
|
|
|
|
return parseSimCatalog({ plans, activationFees, addons });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Get("vpn/plans")
|
|
|
|
|
@RateLimit({ limit: 60, ttl: 60 })
|
2026-02-03 13:12:08 +09:00
|
|
|
@Header(HEADER_CACHE_CONTROL, CACHE_CONTROL_PRIVATE)
|
2025-12-26 17:27:22 +09:00
|
|
|
async getVpnCatalogForAccount(): Promise<VpnCatalogCollection> {
|
2025-12-25 15:48:57 +09:00
|
|
|
const catalog = await this.vpnCatalog.getCatalogData();
|
|
|
|
|
return parseVpnCatalog(catalog);
|
|
|
|
|
}
|
|
|
|
|
}
|