From 22b2f2adce2e4a06171008c3fa119ab1899358bc Mon Sep 17 00:00:00 2001 From: Sharon Dcruz Date: Thu, 18 Sep 2025 10:34:42 +0000 Subject: [PATCH] ClientsLoadingFix (#116) Reviewed-on: https://git.cosqnet.com/cosqnet/fitlien-services/pulls/116 Reviewed-by: Dhansh A S Co-authored-by: Sharon Dcruz Co-committed-by: Sharon Dcruz --- functions/src/index.ts | 1 - functions/src/memberCache/index.ts | 1 - functions/src/memberCache/memberCache.ts | 120 +++++++---------------- 3 files changed, 38 insertions(+), 84 deletions(-) diff --git a/functions/src/index.ts b/functions/src/index.ts index e03316d..b3ee3bf 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -26,7 +26,6 @@ export { export { generateMemberCache, updateTrainerAssignmentCache, - updateTimeSlotCache, getCachedMembers, rebuildGymCachee, batchRebuildCaches diff --git a/functions/src/memberCache/index.ts b/functions/src/memberCache/index.ts index 15ba89b..10c068d 100644 --- a/functions/src/memberCache/index.ts +++ b/functions/src/memberCache/index.ts @@ -1,7 +1,6 @@ export { generateMemberCache, updateTrainerAssignmentCache, - updateTimeSlotCache, getCachedMembers, rebuildGymCachee, batchRebuildCaches diff --git a/functions/src/memberCache/memberCache.ts b/functions/src/memberCache/memberCache.ts index 9a1d5bd..fb3ae5d 100644 --- a/functions/src/memberCache/memberCache.ts +++ b/functions/src/memberCache/memberCache.ts @@ -10,6 +10,7 @@ const CACHE_FOLDER = 'gym_member_cache'; interface MembershipData { gymId?: string; + userId?: string; status?: string; subscription?: { hasPersonalTraining?: boolean; @@ -36,21 +37,14 @@ interface PaymentData { interface TrainerAssignment { id?: string; membershipId?: string; - createdAt?: admin.firestore.Timestamp; - [key: string]: any; -} - -interface TimeSlot { - id?: string; - membershipId?: string; - startTime?: admin.firestore.Timestamp; - endTime?: admin.firestore.Timestamp; + timeSlot?: any[]; createdAt?: admin.firestore.Timestamp; [key: string]: any; } interface CacheEntry { - membershipId: string; + userId: string; + membershipId: string; memberData: { daysUntilExpiry?: number | null; hasPartialPayment: boolean; @@ -81,7 +75,7 @@ export const generateMemberCache = onDocumentWritten( async (event) => { try { const membershipId = event.params.membershipId; - const membershipData = event.data?.after?.exists + const membershipData = event.data?.after?.exists ? event.data.after.data() as MembershipData : null; @@ -144,45 +138,6 @@ export const updateTrainerAssignmentCache = onDocumentWritten( } ); -export const updateTimeSlotCache = onDocumentWritten( - { - region: "#{SERVICES_RGN}#", - document: "scheduled_trainings/{slotId}", - }, - async (event) => { - try { - const slotData = event.data?.after?.exists - ? event.data.after.data() as TimeSlot - : null; - const oldSlotData = event.data?.before?.exists - ? event.data.before.data() as TimeSlot - : null; - - const gymIds = new Set(); - - if (slotData?.membershipId) { - const gymId = await getGymIdFromMembershipId(slotData.membershipId); - if (gymId) gymIds.add(gymId); - } - - if (oldSlotData?.membershipId) { - const gymId = await getGymIdFromMembershipId(oldSlotData.membershipId); - if (gymId) gymIds.add(gymId); - } - - for (const gymId of gymIds) { - await rebuildGymCache(gymId); - } - - if (gymIds.size > 0) { - logger.info(`Updated time slot cache for ${gymIds.size} gym(s)`); - } - } catch (error) { - logger.error('Error updating time slot cache:', error); - } - } -); - export const getCachedMembers = onCall( { region: "#{SERVICES_RGN}#", @@ -302,7 +257,13 @@ async function rebuildGymCache(gymId: string): Promise { const batch = membershipsSnapshot.docs.slice(i, i + batchSize); const batchPromises = batch.map(async (doc) => { try { - return await generateCacheEntry(doc.id, doc.data() as MembershipData); + const membershipData = doc.data() as MembershipData; + const userId = membershipData.userId; + if (!userId) { + logger.warn(`Skipping member with ID ${doc.id} due to missing userId`); + return null; + } + return await generateCacheEntry(userId, doc.id, membershipData); } catch (error) { logger.error(`Error processing member ${doc.id}:`, error); return null; @@ -343,24 +304,30 @@ async function rebuildGymCache(gymId: string): Promise { } } -async function generateCacheEntry(membershipId: string, membershipData: MembershipData): Promise { +async function generateCacheEntry(userId: string, membershipId: string, membershipData: MembershipData): Promise { try { let fields: { [key: string]: string } = {}; try { const clientFieldsSnapshot = await app .firestore() .collection('client_profiles') - .where('membershipId', '==', membershipId) + .where('uid', '==', userId) .get(); if (!clientFieldsSnapshot.empty) { const fieldDoc = clientFieldsSnapshot.docs[0]; const fieldData = fieldDoc.data() as ClientFields; - fields = fieldData.fields || {}; + fields = { + 'first-name': fieldData.fields?.['first-name'] || '', + 'email': fieldData.fields?.['email'] || '', + 'phone-number': fieldData.fields?.['phone-number'] || '', + 'alternate-contact': fieldData.fields?.['alternate-contact'] || '', + }; } } catch (error) { - logger.error(`Error getting fields for ${membershipId}:`, error); + logger.error(`Error getting fields for user ${userId}:`, error); } + let renewalDate: Date | null = null; let daysUntilExpiry: number | null = null; @@ -388,7 +355,7 @@ async function generateCacheEntry(membershipId: string, membershipData: Membersh } } } catch (error) { - logger.error(`Error getting renewal date for ${membershipId}:`, error); + logger.error(`Error getting renewal date for membership ${membershipId}:`, error); } } @@ -407,42 +374,31 @@ async function generateCacheEntry(membershipId: string, membershipData: Membersh .where('membershipId', '==', membershipId) .get(); - trainerAssignments = assignmentsSnapshot.docs.map(doc => { + assignmentsSnapshot.docs.forEach(doc => { const data = doc.data() as TrainerAssignment; - return { - id: doc.id, - ...data, - createdAt: data.createdAt ? data.createdAt.toDate().toISOString() : null - }; - }); - - const timeSlotsSnapshot = await app - .firestore() - .collection('scheduled_trainings') - .where('membershipId', '==', membershipId) - .get(); - - timeSlots = timeSlotsSnapshot.docs.map(doc => { - const data = doc.data() as TimeSlot; - return { - id: doc.id, - ...data, - startTime: data.startTime ? data.startTime.toDate().toISOString() : null, - endTime: data.endTime ? data.endTime.toDate().toISOString() : null, - createdAt: data.createdAt ? data.createdAt.toDate().toISOString() : null - }; + if (data.timeSlot && Array.isArray(data.timeSlot)) { + timeSlots.push(...data.timeSlot); + } + trainerAssignments.push({ id: doc.id }); }); } catch (error) { - logger.error(`Error getting trainer data for ${membershipId}:`, error); + logger.error(`Error getting trainer data for membership ${membershipId}:`, error); } } const cacheEntry: CacheEntry = { + userId, membershipId, memberData: { - ...membershipData, - daysUntilExpiry, + status: membershipData.status, + subscription: { + hasPersonalTraining: membershipData.subscription?.hasPersonalTraining, + frequency: membershipData.subscription?.frequency, + }, + remainingAmount: membershipData.remainingAmount, + isPartialPayment: membershipData.isPartialPayment, hasPartialPayment, + daysUntilExpiry, createdAt: membershipData.createdAt ? membershipData.createdAt.toDate().toISOString() : null, updatedAt: membershipData.updatedAt ? membershipData.updatedAt.toDate().toISOString() : null },