Browse Source

fix: remove customer/order caching from ShopRenter sync #85

- Remove customer and order caching logic from both shoprenter-sync and shoprenter-scheduled-sync Edge Functions
- Tables shoprenter_customers_cache and shoprenter_orders_cache were dropped in migration 20251031_160300 for GDPR compliance
- Customer/order data should now be accessed in real-time via webshop-data-api endpoint
- Update sync stats to only track products
- Fix error handling to only check product sync errors
- Remove unused imports (fetchOrders, fetchCustomers, formatFirstValidPhone)
- Add GDPR compliance comments explaining the changes

This fixes the empty error objects ({}) when syncing customers/orders because the code was trying to insert into non-existent tables.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Claude 5 months ago
parent
commit
1306ac9e31

+ 8 - 43
supabase/functions/shoprenter-scheduled-sync/index.ts

@@ -1,8 +1,8 @@
 import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
 import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
 import { wrapHandler, logError } from '../_shared/error-handler.ts'
-import { fetchProducts, fetchOrders, fetchCustomers } from '../_shared/shoprenter-client.ts'
-import { formatFirstValidPhone, detectCountryCode } from '../_shared/phone-formatter.ts'
+import { fetchProducts } from '../_shared/shoprenter-client.ts'
+import { detectCountryCode } from '../_shared/phone-formatter.ts'
 
 const corsHeaders = {
   'Access-Control-Allow-Origin': '*',
@@ -123,8 +123,7 @@ serve(wrapHandler('shoprenter-scheduled-sync', async (req) => {
         store_id: storeId,
         store_name: store.store_name,
         products: { synced: 0, errors: 0 },
-        customer_access: { available: false, tested: false },
-        order_access: { available: false, tested: false },
+        // Note: customer_access and order_access removed for GDPR compliance (migration 20251031_160300)
         started_at: new Date().toISOString(),
         completed_at: null as string | null,
         status: 'success' as 'success' | 'partial' | 'failed',
@@ -193,42 +192,9 @@ serve(wrapHandler('shoprenter-scheduled-sync', async (req) => {
           }
         }
 
-        // Test customer data access (don't sync, just validate)
-        // Check if store has data_access_permissions.allow_customer_access enabled
-        const { data: storeData } = await supabaseAdmin
-          .from('stores')
-          .select('data_access_permissions')
-          .eq('id', storeId)
-          .single()
-
-        if (storeData?.data_access_permissions?.allow_customer_access) {
-          try {
-            console.log(`[ShopRenter Scheduled Sync] Testing customer data access for store ${storeId}`)
-            const customersTest = await fetchCustomers(storeId, 1, 1)
-            syncStats.customer_access.tested = true
-            syncStats.customer_access.available = !!(customersTest && customersTest.items)
-            console.log(`[ShopRenter Scheduled Sync] Store ${storeId}: Customer access available: ${syncStats.customer_access.available}`)
-          } catch (error) {
-            console.error(`[ShopRenter Scheduled Sync] Customer access test error for store ${storeId}:`, error)
-            syncStats.customer_access.tested = true
-            syncStats.customer_access.available = false
-          }
-        }
-
-        // Test order data access (don't sync, just validate)
-        if (storeData?.data_access_permissions?.allow_order_access) {
-          try {
-            console.log(`[ShopRenter Scheduled Sync] Testing order data access for store ${storeId}`)
-            const ordersTest = await fetchOrders(storeId, 1, 1)
-            syncStats.order_access.tested = true
-            syncStats.order_access.available = !!(ordersTest && ordersTest.items)
-            console.log(`[ShopRenter Scheduled Sync] Store ${storeId}: Order access available: ${syncStats.order_access.available}`)
-          } catch (error) {
-            console.error(`[ShopRenter Scheduled Sync] Order access test error for store ${storeId}:`, error)
-            syncStats.order_access.tested = true
-            syncStats.order_access.available = false
-          }
-        }
+        // Note: Customer and Order testing removed for GDPR compliance (migration 20251031_160300)
+        // Customer/order data is now accessed in real-time via webshop-data-api endpoint
+        console.log(`[ShopRenter Scheduled Sync] Skipping customer/order testing (GDPR compliance - use real-time API access)`)
 
         // Update BOTH stores table and store_sync_config to maintain consistency
         const syncCompletedAt = new Date().toISOString()
@@ -238,9 +204,8 @@ serve(wrapHandler('shoprenter-scheduled-sync', async (req) => {
           ...(store.alt_data || {}),
           last_sync_at: syncCompletedAt,
           last_sync_stats: {
-            products: syncStats.products,
-            customer_access: syncStats.customer_access,
-            order_access: syncStats.order_access
+            products: syncStats.products
+            // Note: customer_access and order_access removed for GDPR compliance
           },
           last_sync_type: 'scheduled'
         }

+ 13 - 148
supabase/functions/shoprenter-sync/index.ts

@@ -1,8 +1,8 @@
 import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
 import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
 import { wrapHandler, logError } from '../_shared/error-handler.ts'
-import { fetchProducts, fetchOrders, fetchCustomers } from '../_shared/shoprenter-client.ts'
-import { formatFirstValidPhone, detectCountryCode } from '../_shared/phone-formatter.ts'
+import { fetchProducts } from '../_shared/shoprenter-client.ts'
+import { detectCountryCode } from '../_shared/phone-formatter.ts'
 import {
   collectionExists,
   createCollection,
@@ -375,9 +375,8 @@ serve(wrapHandler('shoprenter-sync', async (req) => {
     })
 
     const syncStats = {
-      products: { synced: 0, errors: 0 },
-      orders: { synced: 0, errors: 0 },
-      customers: { synced: 0, errors: 0 }
+      products: { synced: 0, errors: 0 }
+      // Note: orders and customers removed for GDPR compliance (migration 20251031_160300)
     }
 
     // supabaseAdmin already created above, reuse it
@@ -462,156 +461,22 @@ serve(wrapHandler('shoprenter-sync', async (req) => {
       syncStats.products.errors++
     }
 
-    // Sync Orders
-    let orderSyncError: Error | null = null
-    try {
-      console.log('[ShopRenter] Syncing orders...')
-      let page = 0  // ShopRenter API uses zero-based pagination
-      let hasMore = true
-      const limit = 50
-
-      while (hasMore) {
-        const ordersData = await fetchOrders(storeId, page, limit)
-
-        if (ordersData.items && ordersData.items.length > 0) {
-          const ordersToCache = ordersData.items.map((order: any) => ({
-            store_id: storeId,
-            shoprenter_order_id: order.id,
-            order_number: order.order_number || order.number || order.id,
-            status: order.status,
-            total: parseFloat(order.total) || 0,
-            currency: order.currency || 'HUF',
-            customer_name: order.customer_name || `${order.customer?.firstname || ''} ${order.customer?.lastname || ''}`.trim() || null,
-            customer_email: order.customer_email || order.customer?.email || null,
-            customer_phone: formatFirstValidPhone([
-              order.customer_phone,
-              order.customer?.phone,
-              order.billing_address?.phone,
-              order.shipping_address?.phone
-            ], countryCode),
-            line_items: order.items || order.line_items || [],
-            billing_address: order.billing_address || null,
-            shipping_address: order.shipping_address || null,
-            order_created_at: order.created_at || order.date_created || new Date().toISOString(),
-            raw_data: order,
-            last_synced_at: new Date().toISOString()
-          }))
-
-          const { error: upsertError } = await supabaseAdmin
-            .from('shoprenter_orders_cache')
-            .upsert(ordersToCache, {
-              onConflict: 'store_id,shoprenter_order_id'
-            })
-
-          if (upsertError) {
-            console.error('[ShopRenter] Error caching orders:', upsertError)
-            syncStats.orders.errors += ordersToCache.length
-          } else {
-            syncStats.orders.synced += ordersToCache.length
-          }
-
-          // Check if there are more pages
-          if (ordersData.pagination && ordersData.pagination.total) {
-            const totalPages = Math.ceil(ordersData.pagination.total / limit)
-            hasMore = page < totalPages - 1  // Zero-based, so last page is totalPages - 1
-          } else {
-            hasMore = ordersData.items.length === limit
-          }
-
-          page++
-        } else {
-          hasMore = false
-        }
-      }
-
-      console.log(`[ShopRenter] Orders synced: ${syncStats.orders.synced}`)
-    } catch (error) {
-      console.error('[ShopRenter] Order sync error:', error)
-      orderSyncError = error as Error
-      syncStats.orders.errors++
-    }
-
-    // Sync Customers
-    let customerSyncError: Error | null = null
-    try {
-      console.log('[ShopRenter] Syncing customers...')
-      let page = 0  // ShopRenter API uses zero-based pagination
-      let hasMore = true
-      const limit = 50
-
-      while (hasMore) {
-        const customersData = await fetchCustomers(storeId, page, limit)
-
-        if (customersData.items && customersData.items.length > 0) {
-          const customersToCache = customersData.items.map((customer: any) => ({
-            store_id: storeId,
-            shoprenter_customer_id: customer.id,
-            email: customer.email,
-            first_name: customer.firstname,
-            last_name: customer.lastname,
-            phone: formatFirstValidPhone([
-              customer.phone,
-              customer.billing_address?.phone,
-              customer.shipping_address?.phone
-            ], countryCode),
-            billing_address: customer.billing_address || null,
-            shipping_address: customer.shipping_address || null,
-            orders_count: customer.orders_count || 0,
-            total_spent: parseFloat(customer.total_spent) || 0,
-            raw_data: customer,
-            last_synced_at: new Date().toISOString()
-          }))
-
-          const { error: upsertError } = await supabaseAdmin
-            .from('shoprenter_customers_cache')
-            .upsert(customersToCache, {
-              onConflict: 'store_id,shoprenter_customer_id'
-            })
-
-          if (upsertError) {
-            console.error('[ShopRenter] Error caching customers:', upsertError)
-            syncStats.customers.errors += customersToCache.length
-          } else {
-            syncStats.customers.synced += customersToCache.length
-          }
-
-          // Check if there are more pages
-          if (customersData.pagination && customersData.pagination.total) {
-            const totalPages = Math.ceil(customersData.pagination.total / limit)
-            hasMore = page < totalPages - 1  // Zero-based, so last page is totalPages - 1
-          } else {
-            hasMore = customersData.items.length === limit
-          }
-
-          page++
-        } else {
-          hasMore = false
-        }
-      }
-
-      console.log(`[ShopRenter] Customers synced: ${syncStats.customers.synced}`)
-    } catch (error) {
-      console.error('[ShopRenter] Customer sync error:', error)
-      customerSyncError = error as Error
-      syncStats.customers.errors++
-    }
+    // Note: Customer and Order caching removed for GDPR compliance (migration 20251031_160300)
+    // Customer/order data is now accessed in real-time via webshop-data-api endpoint
+    console.log('[ShopRenter] Skipping customer/order caching (GDPR compliance - use real-time API access)')
 
     // Update BOTH stores table and store_sync_config to maintain consistency
     const syncCompletedAt = new Date().toISOString()
 
-    // Check if any critical errors occurred
-    const hasErrors = productSyncError || orderSyncError || customerSyncError
-    const totalErrors = syncStats.products.errors + syncStats.orders.errors + syncStats.customers.errors
-    const totalSynced = syncStats.products.synced + syncStats.orders.synced + syncStats.customers.synced
+    // Check if any critical errors occurred (only products now, customer/order removed for GDPR)
+    const hasErrors = productSyncError !== null
+    const totalErrors = syncStats.products.errors
+    const totalSynced = syncStats.products.synced
 
     // Build error message if any errors occurred
     let errorMessage: string | null = null
-    if (hasErrors) {
-      const errorParts: string[] = []
-      if (productSyncError) errorParts.push(`Products: ${productSyncError.message}`)
-      if (orderSyncError) errorParts.push(`Orders: ${orderSyncError.message}`)
-      if (customerSyncError) errorParts.push(`Customers: ${customerSyncError.message}`)
-      errorMessage = errorParts.join('; ')
+    if (hasErrors && productSyncError) {
+      errorMessage = `Products: ${productSyncError.message}`
     }
 
     // Update stores table (for Web UI display)