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.
 
 
 

116 lines
3.0 KiB

import { and, lt, isNull } from 'drizzle-orm'
import { carts } from '../database/schema'
/**
* Cart Cleanup Utilities
*
* These functions prepare the structure for automatic cart cleanup.
* The actual cleanup job will be implemented in a later phase using BullMQ.
*
* Cleanup Strategy:
* - User carts: Keep until updated_at > CART_EXPIRY_DAYS
* - Guest carts: Keep until updated_at > CART_EXPIRY_DAYS
* - Rationale: Inactive carts consume database space and should be pruned
*
* Future Implementation:
* - BullMQ scheduled job runs daily at night (e.g., 3 AM)
* - Calls getExpiredCarts() to find carts to delete
* - Deletes expired carts (cascade deletes cart_items automatically)
* - Logs cleanup statistics for monitoring
*/
/**
* Get carts that are older than the configured expiry period
*
* @returns Array of expired cart IDs
*/
export async function getExpiredCarts(): Promise<string[]> {
const db = useDatabase()
const config = useRuntimeConfig()
// Calculate expiry date
const expiryDays = config.cart.expiryDays
const expiryDate = new Date()
expiryDate.setDate(expiryDate.getDate() - expiryDays)
// Find carts not updated since expiry date
const expiredCarts = await db
.select({ id: carts.id })
.from(carts)
.where(lt(carts.updatedAt, expiryDate))
return expiredCarts.map((cart) => cart.id)
}
/**
* Delete expired carts
*
* Note: cart_items are automatically deleted via CASCADE foreign key constraint
*
* @param cartIds - Array of cart UUIDs to delete
* @returns Number of carts deleted
*/
export async function deleteExpiredCarts(cartIds: string[]): Promise<number> {
if (cartIds.length === 0) {
return 0
}
const db = useDatabase()
// Delete carts (cart_items cascade automatically)
const result = await db
.delete(carts)
.where(
and(
...cartIds.map((id) => eq(carts.id, id))
)
)
return cartIds.length
}
/**
* Get cleanup statistics
*
* @returns Statistics about carts in the database
*/
export async function getCartStatistics() {
const db = useDatabase()
const config = useRuntimeConfig()
// Calculate expiry date
const expiryDays = config.cart.expiryDays
const expiryDate = new Date()
expiryDate.setDate(expiryDate.getDate() - expiryDays)
// Count carts by type
const [totalCarts] = await db.select({ count: count() }).from(carts)
const [userCarts] = await db
.select({ count: count() })
.from(carts)
.where(isNull(carts.userId).not())
const [guestCarts] = await db
.select({ count: count() })
.from(carts)
.where(isNull(carts.userId))
const [expiredCarts] = await db
.select({ count: count() })
.from(carts)
.where(lt(carts.updatedAt, expiryDate))
return {
totalCarts: totalCarts?.count || 0,
userCarts: userCarts?.count || 0,
guestCarts: guestCarts?.count || 0,
expiredCarts: expiredCarts?.count || 0,
expiryDays,
expiryDate: expiryDate.toISOString(),
}
}
// Note: Import count function
import { count } from 'drizzle-orm'
import { eq } from 'drizzle-orm'