All files / src/lib/cart cart-merge.ts

47.91% Statements 46/96
100% Branches 3/3
42.85% Functions 3/7
47.91% Lines 46/96

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 971x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x                                                     1x 1x 1x 1x 1x                   1x 1x 1x 1x 1x                 1x 1x 1x 1x 1x                
/**
 * Cart Merge Logic (Server-Side)
 *
 * Contains database operations for cart merging.
 * For client-safe utilities, use cart-merge-utils.ts instead.
 *
 * @server-only
 */
 
import { prisma } from '@/lib/prisma';
import { CartItem } from '@/redux/features/cartSlice';
import { logger } from '@/lib/logging';
 
// Re-export client-safe utilities for convenience when importing on server
export {
  mergeAnonymousCartToUser,
  transformDbCartToCartItems,
  validateCartItems,
  type MergeResult,
  type ConflictItem } from './cart-merge-utils';
 
/**
 * Apply cart merge to database
 *
 * This function clears the user's current cart and replaces it with the merged items
 *
 * @param userId - User ID
 * @param mergedItems - Merged cart items
 * @param deviceId - Device identifier
 */
export async function applyCartMerge(
  userId: number,
  mergedItems: CartItem[],
  deviceId: string = 'default'
): Promise<void> {
  try {
    await prisma.$transaction(async (tx) => {
      // Delete existing cart items for this user
      await tx.cart.deleteMany({
        where: { userId }});

      // Insert merged items
      if (mergedItems.length > 0) {
        await tx.cart.createMany({
          data: mergedItems.map((item) => ({
            userId,
            productId: item.id,
            quantity: item.quantity,
            deviceId,
            syncedAt: new Date()}))});
      }
    });
  } catch (error) {
    logger.error('Failed to apply cart merge', error instanceof Error ? error : new Error(String(error)), { category: 'CART' });
    throw new Error('Failed to apply cart merge to database');
  }
}
 
/**
 * Get cart items that need to be synced (have stale flag)
 */
export async function getStaleCartItems(userId: number) {
  return await prisma.cart.findMany({
    where: {
      userId,
      isStale: true},
    include: {
      product: {
        include: {
          images: true}}}});
}
 
/**
 * Mark cart items as stale (for conflict resolution)
 */
export async function markCartItemsAsStale(userId: number, productIds: number[]) {
  await prisma.cart.updateMany({
    where: {
      userId,
      productId: {
        in: productIds}},
    data: {
      isStale: true}});
}
 
/**
 * Clear stale flags from cart items
 */
export async function clearStaleFlags(userId: number) {
  await prisma.cart.updateMany({
    where: {
      userId,
      isStale: true},
    data: {
      isStale: false}});
}