feature/fitlien-828 #120
| @ -26,7 +26,6 @@ export { | ||||
| export { | ||||
|   generateMemberCache, | ||||
|   updateTrainerAssignmentCache, | ||||
|   updateTimeSlotCache, | ||||
|   getCachedMembers, | ||||
|   rebuildGymCachee, | ||||
|   batchRebuildCaches | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| export { | ||||
|   generateMemberCache, | ||||
|   updateTrainerAssignmentCache, | ||||
|   updateTimeSlotCache, | ||||
|   getCachedMembers, | ||||
|   rebuildGymCachee, | ||||
|   batchRebuildCaches | ||||
|  | ||||
| @ -10,6 +10,7 @@ const CACHE_FOLDER = 'gym_member_cache'; | ||||
| 
 | ||||
| interface MembershipData { | ||||
|   gymId?: string; | ||||
|   userId?: string;  | ||||
|   status?: string; | ||||
|   subscription?: { | ||||
|     hasPersonalTraining?: boolean; | ||||
| @ -36,20 +37,13 @@ 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 { | ||||
|   userId: string;  | ||||
|   membershipId: string;  | ||||
|   memberData: { | ||||
|     daysUntilExpiry?: number | 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<string>(); | ||||
|        | ||||
|       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<void> { | ||||
|       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<void> { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| async function generateCacheEntry(membershipId: string, membershipData: MembershipData): Promise<CacheEntry> { | ||||
| async function generateCacheEntry(userId: string, membershipId: string, membershipData: MembershipData): Promise<CacheEntry> { | ||||
|   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 | ||||
|       }, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user