You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.2 KiB
91 lines
2.2 KiB
/**
|
|
* 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,
|
|
}
|
|
})
|
|
|