diff --git a/dashboard-server/klaviyo-server/services/events.service.js b/dashboard-server/klaviyo-server/services/events.service.js index ec25d58..844fd73 100644 --- a/dashboard-server/klaviyo-server/services/events.service.js +++ b/dashboard-server/klaviyo-server/services/events.service.js @@ -1290,10 +1290,10 @@ export class EventsService { // Transform and flatten the events into a single array const allEvents = []; - results.forEach((result, index) => { - const metricId = metrics[index]; - const events = result.data || []; - allEvents.push(...events); + results.forEach((result) => { + if (result && Array.isArray(result.data)) { + allEvents.push(...result.data); + } }); // Sort all events by datetime in descending order @@ -1303,12 +1303,22 @@ export class EventsService { return dateB - dateA; }); - return { + const result = { data: allEvents, meta: { total_count: allEvents.length } }; + + // Cache the result + try { + const ttl = this.redisService._getTTL(timeRange); + await this.redisService.set(`${cacheKey}:feed`, result, ttl); + } catch (cacheError) { + console.warn('[EventsService] Cache set error:', cacheError); + } + + return result; } catch (error) { console.error('[EventsService] Error in batch metrics:', error); throw error; @@ -1540,6 +1550,7 @@ export class EventsService { // Transform events const transformedEvents = this._transformEvents(currentEvents.data || []); + console.log(`[EventsService] Processing ${transformedEvents.length} ${metric}`); // Initialize daily stats map with all dates in range using TimeManager's day start const dailyStats = new Map(); @@ -1557,35 +1568,59 @@ export class EventsService { currentDate = this.timeManager.getDayStart(currentDate.plus({ days: 1 })); } - // Process events + // Aggregate all reasons and items for the entire period + const periodStats = { + total: 0, + count: 0, + reasons: {}, + items: [] + }; + + // Process current period events for (const event of transformedEvents) { const datetime = this.timeManager.toDateTime(event.attributes?.datetime); if (!datetime) continue; - // Get the day start for this event's time - const dayStart = this.timeManager.getDayStart(datetime); - const dateKey = dayStart.toFormat('yyyy-MM-dd'); - if (!dailyStats.has(dateKey)) continue; - - const dayStats = dailyStats.get(dateKey); const props = event.event_properties || {}; const amount = Number(metric === 'refunds' ? props.PaymentAmount : props.TotalAmount || 0); const reason = props.CancelReason || props.OrderMessage || 'No reason provided'; const orderId = props.OrderId || props.FromOrder; - dayStats.total += amount; - dayStats.count++; - dayStats.reasons[reason] = (dayStats.reasons[reason] || 0) + 1; - dayStats.items.push({ + const item = { orderId, amount, reason, datetime: datetime.toISO() - }); + }; - dailyStats.set(dateKey, dayStats); + // Always update period totals for events within the period + periodStats.total += amount; + periodStats.count++; + periodStats.reasons[reason] = (periodStats.reasons[reason] || 0) + 1; + periodStats.items.push(item); + + // Get the day start for this event's time + const dayStart = this.timeManager.getDayStart(datetime); + const dateKey = dayStart.toFormat('yyyy-MM-dd'); + + // Update daily stats if we have this day in our map + if (dailyStats.has(dateKey)) { + const dayStats = dailyStats.get(dateKey); + dayStats.total += amount; + dayStats.count++; + dayStats.reasons[reason] = (dayStats.reasons[reason] || 0) + 1; + dayStats.items.push(item); + dailyStats.set(dateKey, dayStats); + } } + console.log(`[EventsService] Period stats for ${metric}:`, { + total: periodStats.total, + count: periodStats.count, + reasonCount: Object.keys(periodStats.reasons).length, + itemCount: periodStats.items.length + }); + // Convert to array and sort by date const stats = Array.from(dailyStats.values()) .sort((a, b) => a.date.localeCompare(b.date)) @@ -1594,8 +1629,12 @@ export class EventsService { [metric === 'refunds' ? 'refunds' : 'canceledOrders']: { total: day.total, count: day.count, - reasons: day.reasons, - items: day.items + reasons: periodStats.reasons, // Use period-wide reasons for each day + items: day.items, + periodTotal: periodStats.total, + periodCount: periodStats.count, + periodReasons: periodStats.reasons, + periodItems: periodStats.items } })); diff --git a/dashboard/src/components/dashboard/StatCards.jsx b/dashboard/src/components/dashboard/StatCards.jsx index 4c91dc9..bbd3fc0 100644 --- a/dashboard/src/components/dashboard/StatCards.jsx +++ b/dashboard/src/components/dashboard/StatCards.jsx @@ -290,8 +290,7 @@ const CancellationsDetails = ({ data }) => { const reasonData = Object.entries(cancelData.reasons || {}) .map(([reason, count]) => ({ reason, - count, - percentage: (count / cancelData.count) * 100 + count })) .sort((a, b) => b.count - a.count); @@ -328,7 +327,6 @@ const CancellationsDetails = ({ data }) => { Reason Count - % of Total @@ -336,7 +334,6 @@ const CancellationsDetails = ({ data }) => { {item.reason} {item.count.toLocaleString()} - {item.percentage.toFixed(1)}% ))} @@ -629,8 +626,7 @@ const RefundDetails = ({ data }) => { const reasonData = Object.entries(refundData.reasons || {}) .map(([reason, count]) => ({ reason, - count, - percentage: (count / refundData.count) * 100 + count })) .sort((a, b) => b.count - a.count); @@ -667,7 +663,6 @@ const RefundDetails = ({ data }) => { Reason Count - % of Total @@ -675,7 +670,6 @@ const RefundDetails = ({ data }) => { {item.reason} {item.count.toLocaleString()} - {item.percentage.toFixed(1)}% ))}