feature/fitlien-828 #120
| @ -26,7 +26,6 @@ export { | |||||||
| export { | export { | ||||||
|   generateMemberCache, |   generateMemberCache, | ||||||
|   updateTrainerAssignmentCache, |   updateTrainerAssignmentCache, | ||||||
|   updateTimeSlotCache, |  | ||||||
|   getCachedMembers, |   getCachedMembers, | ||||||
|   rebuildGymCachee, |   rebuildGymCachee, | ||||||
|   batchRebuildCaches |   batchRebuildCaches | ||||||
|  | |||||||
| @ -1,7 +1,6 @@ | |||||||
| export { | export { | ||||||
|   generateMemberCache, |   generateMemberCache, | ||||||
|   updateTrainerAssignmentCache, |   updateTrainerAssignmentCache, | ||||||
|   updateTimeSlotCache, |  | ||||||
|   getCachedMembers, |   getCachedMembers, | ||||||
|   rebuildGymCachee, |   rebuildGymCachee, | ||||||
|   batchRebuildCaches |   batchRebuildCaches | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ const CACHE_FOLDER = 'gym_member_cache'; | |||||||
| 
 | 
 | ||||||
| interface MembershipData { | interface MembershipData { | ||||||
|   gymId?: string; |   gymId?: string; | ||||||
|  |   userId?: string;  | ||||||
|   status?: string; |   status?: string; | ||||||
|   subscription?: { |   subscription?: { | ||||||
|     hasPersonalTraining?: boolean; |     hasPersonalTraining?: boolean; | ||||||
| @ -36,21 +37,14 @@ interface PaymentData { | |||||||
| interface TrainerAssignment { | interface TrainerAssignment { | ||||||
|   id?: string; |   id?: string; | ||||||
|   membershipId?: string; |   membershipId?: string; | ||||||
|   createdAt?: admin.firestore.Timestamp; |   timeSlot?: any[];  | ||||||
|   [key: string]: any; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| interface TimeSlot { |  | ||||||
|   id?: string; |  | ||||||
|   membershipId?: string; |  | ||||||
|   startTime?: admin.firestore.Timestamp; |  | ||||||
|   endTime?: admin.firestore.Timestamp; |  | ||||||
|   createdAt?: admin.firestore.Timestamp; |   createdAt?: admin.firestore.Timestamp; | ||||||
|   [key: string]: any; |   [key: string]: any; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface CacheEntry { | interface CacheEntry { | ||||||
|   membershipId: string; |   userId: string;  | ||||||
|  |   membershipId: string;  | ||||||
|   memberData: { |   memberData: { | ||||||
|     daysUntilExpiry?: number | null; |     daysUntilExpiry?: number | null; | ||||||
|     hasPartialPayment: boolean; |     hasPartialPayment: boolean; | ||||||
| @ -81,7 +75,7 @@ export const generateMemberCache = onDocumentWritten( | |||||||
|   async (event) => { |   async (event) => { | ||||||
|     try { |     try { | ||||||
|       const membershipId = event.params.membershipId; |       const membershipId = event.params.membershipId; | ||||||
|             const membershipData = event.data?.after?.exists  |       const membershipData = event.data?.after?.exists  | ||||||
|         ? event.data.after.data() as MembershipData  |         ? event.data.after.data() as MembershipData  | ||||||
|         : null; |         : 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( | export const getCachedMembers = onCall( | ||||||
|   { |   { | ||||||
|     region: "#{SERVICES_RGN}#", |     region: "#{SERVICES_RGN}#", | ||||||
| @ -302,7 +257,13 @@ async function rebuildGymCache(gymId: string): Promise<void> { | |||||||
|       const batch = membershipsSnapshot.docs.slice(i, i + batchSize); |       const batch = membershipsSnapshot.docs.slice(i, i + batchSize); | ||||||
|       const batchPromises = batch.map(async (doc) => { |       const batchPromises = batch.map(async (doc) => { | ||||||
|         try { |         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) { |         } catch (error) { | ||||||
|           logger.error(`Error processing member ${doc.id}:`, error); |           logger.error(`Error processing member ${doc.id}:`, error); | ||||||
|           return null; |           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 { |   try { | ||||||
|     let fields: { [key: string]: string } = {}; |     let fields: { [key: string]: string } = {}; | ||||||
|     try { |     try { | ||||||
|       const clientFieldsSnapshot = await app |       const clientFieldsSnapshot = await app | ||||||
|         .firestore() |         .firestore() | ||||||
|         .collection('client_profiles') |         .collection('client_profiles') | ||||||
|         .where('membershipId', '==', membershipId) |         .where('uid', '==', userId) | ||||||
|         .get(); |         .get(); | ||||||
|        |        | ||||||
|       if (!clientFieldsSnapshot.empty) { |       if (!clientFieldsSnapshot.empty) { | ||||||
|         const fieldDoc = clientFieldsSnapshot.docs[0]; |         const fieldDoc = clientFieldsSnapshot.docs[0]; | ||||||
|         const fieldData = fieldDoc.data() as ClientFields; |         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) { |     } 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 renewalDate: Date | null = null; | ||||||
|     let daysUntilExpiry: number | null = null; |     let daysUntilExpiry: number | null = null; | ||||||
|      |      | ||||||
| @ -388,7 +355,7 @@ async function generateCacheEntry(membershipId: string, membershipData: Membersh | |||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } catch (error) { |       } 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) |           .where('membershipId', '==', membershipId) | ||||||
|           .get(); |           .get(); | ||||||
|          |          | ||||||
|         trainerAssignments = assignmentsSnapshot.docs.map(doc => { |         assignmentsSnapshot.docs.forEach(doc => { | ||||||
|           const data = doc.data() as TrainerAssignment; |           const data = doc.data() as TrainerAssignment; | ||||||
|           return { |           if (data.timeSlot && Array.isArray(data.timeSlot)) { | ||||||
|             id: doc.id, |             timeSlots.push(...data.timeSlot); | ||||||
|             ...data, |           } | ||||||
|             createdAt: data.createdAt ? data.createdAt.toDate().toISOString() : null |           trainerAssignments.push({ id: doc.id }); | ||||||
|           }; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         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 |  | ||||||
|           }; |  | ||||||
|         }); |         }); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         logger.error(`Error getting trainer data for ${membershipId}:`, error); |         logger.error(`Error getting trainer data for membership ${membershipId}:`, error); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const cacheEntry: CacheEntry = { |     const cacheEntry: CacheEntry = { | ||||||
|  |       userId, | ||||||
|       membershipId, |       membershipId, | ||||||
|       memberData: { |       memberData: { | ||||||
|         ...membershipData, |         status: membershipData.status, | ||||||
|         daysUntilExpiry, |         subscription: { | ||||||
|  |           hasPersonalTraining: membershipData.subscription?.hasPersonalTraining, | ||||||
|  |           frequency: membershipData.subscription?.frequency, | ||||||
|  |         }, | ||||||
|  |         remainingAmount: membershipData.remainingAmount, | ||||||
|  |         isPartialPayment: membershipData.isPartialPayment, | ||||||
|         hasPartialPayment, |         hasPartialPayment, | ||||||
|  |         daysUntilExpiry, | ||||||
|         createdAt: membershipData.createdAt ? membershipData.createdAt.toDate().toISOString() : null, |         createdAt: membershipData.createdAt ? membershipData.createdAt.toDate().toISOString() : null, | ||||||
|         updatedAt: membershipData.updatedAt ? membershipData.updatedAt.toDate().toISOString() : null |         updatedAt: membershipData.updatedAt ? membershipData.updatedAt.toDate().toISOString() : null | ||||||
|       }, |       }, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user