2025-12-17 17:59:55 +09:00
|
|
|
import { Body, Controller, Get, Post, Req, UseGuards, UsePipes } from "@nestjs/common";
|
|
|
|
|
import { ZodValidationPipe } from "nestjs-zod";
|
|
|
|
|
import { z } from "zod";
|
|
|
|
|
import type { RequestWithUser } from "@bff/modules/auth/auth.types.js";
|
|
|
|
|
import { RateLimit, RateLimitGuard } from "@bff/core/rate-limiting/index.js";
|
2025-12-23 17:53:08 +09:00
|
|
|
import { InternetCatalogService } from "./services/internet-catalog.service.js";
|
2025-12-17 17:59:55 +09:00
|
|
|
import { addressSchema } from "@customer-portal/domain/customer";
|
2025-12-23 17:53:08 +09:00
|
|
|
import type { InternetEligibilityDetails } from "@customer-portal/domain/catalog";
|
2025-12-17 17:59:55 +09:00
|
|
|
|
|
|
|
|
const eligibilityRequestSchema = z.object({
|
|
|
|
|
notes: z.string().trim().max(2000).optional(),
|
|
|
|
|
address: addressSchema.partial().optional(),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
type EligibilityRequest = z.infer<typeof eligibilityRequestSchema>;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Internet Eligibility Controller
|
|
|
|
|
*
|
|
|
|
|
* Authenticated endpoints for:
|
|
|
|
|
* - fetching current Salesforce eligibility value
|
|
|
|
|
* - requesting a (manual) eligibility/availability check
|
|
|
|
|
*
|
|
|
|
|
* Note: CatalogController is @Public, so we keep these endpoints in a separate controller
|
|
|
|
|
* to ensure GlobalAuthGuard enforces authentication.
|
|
|
|
|
*/
|
|
|
|
|
@Controller("catalog/internet")
|
|
|
|
|
@UseGuards(RateLimitGuard)
|
|
|
|
|
export class InternetEligibilityController {
|
|
|
|
|
constructor(private readonly internetCatalog: InternetCatalogService) {}
|
|
|
|
|
|
|
|
|
|
@Get("eligibility")
|
|
|
|
|
@RateLimit({ limit: 60, ttl: 60 }) // 60/min per IP (cheap)
|
2025-12-23 17:53:08 +09:00
|
|
|
async getEligibility(@Req() req: RequestWithUser): Promise<InternetEligibilityDetails> {
|
2025-12-19 15:15:36 +09:00
|
|
|
return this.internetCatalog.getEligibilityDetailsForUser(req.user.id);
|
2025-12-17 17:59:55 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Post("eligibility-request")
|
|
|
|
|
@RateLimit({ limit: 5, ttl: 300 }) // 5 per 5 minutes per IP
|
|
|
|
|
@UsePipes(new ZodValidationPipe(eligibilityRequestSchema))
|
|
|
|
|
async requestEligibility(
|
|
|
|
|
@Req() req: RequestWithUser,
|
|
|
|
|
@Body() body: EligibilityRequest
|
|
|
|
|
): Promise<{ requestId: string }> {
|
|
|
|
|
const requestId = await this.internetCatalog.requestEligibilityCheckForUser(req.user.id, {
|
|
|
|
|
email: req.user.email,
|
|
|
|
|
...body,
|
|
|
|
|
});
|
|
|
|
|
return { requestId };
|
|
|
|
|
}
|
|
|
|
|
}
|