import { Body, Controller, Post, Request, UsePipes, Inject } from "@nestjs/common"; import { Logger } from "nestjs-pino"; import { ZodValidationPipe } from "@bff/core/validation"; import { CheckoutService } from "../services/checkout.service"; import { CheckoutCart, checkoutCartSchema, checkoutBuildCartRequestSchema, checkoutBuildCartResponseSchema, type CheckoutBuildCartRequest, } from "@customer-portal/domain/orders"; import { apiSuccessResponseSchema } from "@customer-portal/domain/common"; import { z } from "zod"; import type { RequestWithUser } from "@bff/modules/auth/auth.types"; const validateCartResponseSchema = apiSuccessResponseSchema(z.object({ valid: z.boolean() })); @Controller("checkout") export class CheckoutController { constructor( private readonly checkoutService: CheckoutService, @Inject(Logger) private readonly logger: Logger ) {} @Post("cart") @UsePipes(new ZodValidationPipe(checkoutBuildCartRequestSchema)) async buildCart(@Request() req: RequestWithUser, @Body() body: CheckoutBuildCartRequest) { this.logger.log("Building checkout cart", { userId: req.user?.id, orderType: body.orderType, }); try { const cart = await this.checkoutService.buildCart( body.orderType, body.selections, body.configuration ); return checkoutBuildCartResponseSchema.parse({ success: true, data: cart, }); } catch (error) { this.logger.error("Failed to build checkout cart", { error: error instanceof Error ? error.message : String(error), userId: req.user?.id, orderType: body.orderType, }); throw error; } } @Post("validate") @UsePipes(new ZodValidationPipe(checkoutCartSchema)) validateCart(@Body() cart: CheckoutCart) { this.logger.log("Validating checkout cart", { itemCount: cart.items.length, }); try { this.checkoutService.validateCart(cart); return validateCartResponseSchema.parse({ success: true, data: { valid: true }, }); } catch (error) { this.logger.error("Checkout cart validation failed", { error: error instanceof Error ? error.message : String(error), itemCount: cart.items.length, }); throw error; } } }