Assist_Design/apps/bff/src/modules/services/account-services.controller.ts
barsa f257ffe35a Refactor SupportCaseDetailView for improved state management and component structure
- Extracted case detail logic into a custom hook `useCaseDetailState` for better separation of concerns.
- Created sub-components: `CaseNotFoundView`, `CaseHeaderCard`, `CaseMetaInfoRow`, `CaseConversationSection`, `ReplyForm`, and `ClosedCaseNotice` to enhance readability and maintainability.
- Updated message bubble rendering to use `MessageBubbleHeader` and `MessageBubbleStatus` for clearer status indication.
- Improved loading and error handling in `ResidenceCardVerificationSettingsView` by creating dedicated content components for different states.
- Refactored `transformWhmcsSubscriptionListResponse` to enhance readability and maintainability.
- Minor code style adjustments for consistency and clarity across various files.
2026-02-03 13:12:08 +09:00

65 lines
2.6 KiB
TypeScript

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";
import { InternetServicesService } from "./application/internet-services.service.js";
import { SimServicesService } from "./application/sim-services.service.js";
import { VpnServicesService } from "./application/vpn-services.service.js";
import { SalesforceReadThrottleGuard } from "@bff/integrations/salesforce/guards/salesforce-read-throttle.guard.js";
const HEADER_CACHE_CONTROL = "Cache-Control";
const CACHE_CONTROL_PRIVATE = "private, no-store";
@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
@Header(HEADER_CACHE_CONTROL, CACHE_CONTROL_PRIVATE) // personalized
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 })
@Header(HEADER_CACHE_CONTROL, CACHE_CONTROL_PRIVATE) // personalized
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 })
@Header(HEADER_CACHE_CONTROL, CACHE_CONTROL_PRIVATE)
async getVpnCatalogForAccount(): Promise<VpnCatalogCollection> {
const catalog = await this.vpnCatalog.getCatalogData();
return parseVpnCatalog(catalog);
}
}