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.
100 lines
2.4 KiB
100 lines
2.4 KiB
import { eq } from 'drizzle-orm'
|
|
import { products } from '../database/schema'
|
|
import type { H3Event } from 'h3'
|
|
|
|
/**
|
|
* Validate product availability for adding to cart
|
|
*
|
|
* Checks:
|
|
* - Product exists
|
|
* - Product is active
|
|
* - Product has sufficient stock
|
|
* - User has permission to view product (role-based visibility)
|
|
*
|
|
* @param event - H3 event object
|
|
* @param productId - Product UUID
|
|
* @param quantity - Requested quantity
|
|
* @returns Product details if valid
|
|
* @throws H3Error if validation fails
|
|
*/
|
|
export async function validateProductForCart(
|
|
event: H3Event,
|
|
productId: string,
|
|
quantity: number
|
|
) {
|
|
const db = useDatabase()
|
|
|
|
// Fetch product
|
|
const product = await db.query.products.findFirst({
|
|
where: eq(products.id, productId),
|
|
})
|
|
|
|
if (!product) {
|
|
throw createError({
|
|
statusCode: 404,
|
|
statusMessage: 'Product not found',
|
|
})
|
|
}
|
|
|
|
// Check if product is active
|
|
if (!product.active) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: 'This product is no longer available',
|
|
})
|
|
}
|
|
|
|
// Check stock availability
|
|
if (product.stockQuantity < quantity) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: `Insufficient stock. Only ${product.stockQuantity} available.`,
|
|
})
|
|
}
|
|
|
|
// Check role-based visibility
|
|
const { user } = await getUserSession(event)
|
|
|
|
if (!user) {
|
|
// Guest users cannot see products (MVP: no products visible to unauthenticated users)
|
|
throw createError({
|
|
statusCode: 403,
|
|
statusMessage: 'Please log in to add items to your cart',
|
|
})
|
|
}
|
|
|
|
// Check if user has permission to view this product
|
|
const canView = await isProductVisibleForUser(productId, user.id)
|
|
|
|
if (!canView) {
|
|
throw createError({
|
|
statusCode: 404,
|
|
statusMessage: 'Product not found',
|
|
})
|
|
}
|
|
|
|
return product
|
|
}
|
|
|
|
/**
|
|
* Validate quantity update for cart item
|
|
*
|
|
* @param newQuantity - New quantity value
|
|
* @param stockQuantity - Available stock
|
|
* @throws H3Error if validation fails
|
|
*/
|
|
export function validateQuantityUpdate(newQuantity: number, stockQuantity: number): void {
|
|
if (newQuantity < 1) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: 'Quantity must be at least 1',
|
|
})
|
|
}
|
|
|
|
if (newQuantity > stockQuantity) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: `Insufficient stock. Only ${stockQuantity} available.`,
|
|
})
|
|
}
|
|
}
|
|
|