/** * POST /api/cart/items * * Add a product to the shopping cart * * Request Body: * { * productId: string (UUID) * quantity: number (positive integer, default: 1) * } * * Behavior: * - If product already in cart, increments quantity * - Validates product exists, is active, and has sufficient stock * - Checks role-based visibility permissions * - Creates cart if it doesn't exist * * Response: * { * success: true, * message: string, * cart: CartSummary * } */ import { z } from 'zod' import { eq, and } from 'drizzle-orm' import { cartItems } from '../../database/schema' // Request validation schema const addToCartSchema = z.object({ productId: z.string().uuid('Invalid product ID'), quantity: z.number().int().positive().default(1), }) export default defineEventHandler(async (event) => { // Validate request body const body = await readBody(event) const { productId, quantity } = await addToCartSchema.parseAsync(body) // Validate product availability and permissions const product = await validateProductForCart(event, productId, quantity) // Get or create cart const cart = await getOrCreateCart(event) const db = await useDatabase() // Check if product already in cart const existingItem = await db.query.cartItems.findFirst({ where: and( eq(cartItems.cartId, cart.id), eq(cartItems.productId, productId) ), }) if (existingItem) { // Product already in cart - increment quantity const newQuantity = existingItem.quantity + quantity // Validate new quantity against stock validateQuantityUpdate(newQuantity, product.stockQuantity) // Update quantity await db .update(cartItems) .set({ quantity: newQuantity }) .where(eq(cartItems.id, existingItem.id)) } else { // Add new item to cart await db.insert(cartItems).values({ cartId: cart.id, productId, quantity, }) } // Update cart timestamp await touchCart(cart.id) // Return updated cart const cartSummary = await getCartWithItems(cart.id) return { success: true, message: existingItem ? `Quantity updated to ${existingItem.quantity + quantity}` : 'Product added to cart', cart: cartSummary, } })