CognxSafeTrack commited on
Commit
cd7ba04
·
1 Parent(s): 47c20fe

fix: Implement 5-minute re-validation window and Flow Sync Logging

Browse files
apps/whatsapp-worker/src/services/whatsapp-logic.ts CHANGED
@@ -269,13 +269,38 @@ export class WhatsAppLogic {
269
  }
270
  }
271
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  const pendingProgress = await prisma.userProgress.findFirst({
273
- where: { userId: user.id, exerciseStatus: { in: ['PENDING', 'PENDING_REMEDIATION', 'PENDING_DEEPDIVE'] }, trackId: activeEnrollment.trackId },
 
 
 
 
274
  });
275
 
276
  if (pendingProgress) {
277
  const trackDay = await prisma.trackDay.findFirst({ where: { trackId: activeEnrollment.trackId, dayNumber: activeEnrollment.currentDay } });
278
  if (trackDay) {
 
279
  const isDeepDiveAction = pendingProgress.exerciseStatus === 'PENDING_DEEPDIVE';
280
  const wordCount = (text || '').trim().split(/\s+/).length;
281
  if (wordCount < 3) {
 
269
  }
270
  }
271
 
272
+ // 🚨 FLOW-SYNC: Identify current pedagogical state
273
+ const userProgress = await prisma.userProgress.findUnique({
274
+ where: { userId_trackId: { userId: user.id, trackId: activeEnrollment.trackId } }
275
+ });
276
+
277
+ console.log(`[FLOW-SYNC] User ${user.id} at Day ${activeEnrollment.currentDay}, status: ${userProgress?.exerciseStatus}`);
278
+
279
+ const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000);
280
+ const isRecentlyCompleted = userProgress?.exerciseStatus === 'COMPLETED' && userProgress.updatedAt > fiveMinutesAgo;
281
+ const shouldForceRevalidation = !!imageUrl || isRecentlyCompleted;
282
+
283
+ if (shouldForceRevalidation && userProgress?.exerciseStatus === 'COMPLETED') {
284
+ console.log(`[FLOW-SYNC] 🔄 Re-validation triggered for User ${user.id} (Reason: ${imageUrl ? 'New Image' : 'Recent Correction'})`);
285
+ // Briefly reset to PENDING to allow the analysis block below to pick it up
286
+ await prisma.userProgress.update({
287
+ where: { id: userProgress.id },
288
+ data: { exerciseStatus: 'PENDING' }
289
+ });
290
+ }
291
+
292
  const pendingProgress = await prisma.userProgress.findFirst({
293
+ where: {
294
+ userId: user.id,
295
+ exerciseStatus: { in: ['PENDING', 'PENDING_REMEDIATION', 'PENDING_DEEPDIVE'] },
296
+ trackId: activeEnrollment.trackId
297
+ },
298
  });
299
 
300
  if (pendingProgress) {
301
  const trackDay = await prisma.trackDay.findFirst({ where: { trackId: activeEnrollment.trackId, dayNumber: activeEnrollment.currentDay } });
302
  if (trackDay) {
303
+ console.log(`[FLOW-SYNC] 🧠 User ${user.id} is at Day ${activeEnrollment.currentDay}, processing response for Day ${activeEnrollment.currentDay}.`);
304
  const isDeepDiveAction = pendingProgress.exerciseStatus === 'PENDING_DEEPDIVE';
305
  const wordCount = (text || '').trim().split(/\s+/).length;
306
  if (wordCount < 3) {
tasks/lessons.md CHANGED
@@ -13,6 +13,7 @@ Ce fichier archive les échecs et solutions liées à la **stabilité technique*
13
  - **[QUEUES] Payload Sync** : S'assurer que les noms de champs dans `whatsappQueue.add` (producteur) matchent exactement le destructuring dans le worker (consommateur). Préférer `currentDay` partout pour la consistance.
14
  - **[DB] Enrollment ID** : Toujours passer l'ID d'inscription (`enrollmentId`) au job de feedback pour permettre la persistance des réponses sans crash Prisma.
15
  - **[JSON] Null Safety & Expansion** : Toujours vérifier la présence de données (Null Safety) lors de l'extension des schémas JSON, sous peine de briser le pipeline des jours précédents (Utiliser des guards `currentDay >= X`).
 
16
  - **[UX] Guidance Post-Validation** : Si un utilisateur envoie un message alors qu'il est en statut `COMPLETED`, le système ne doit pas rester muet. Il doit lui renvoyer un message de navigation (ex: "Tape SUITE pour continuer").
17
 
18
  ## 🛡️ Règle d'Or de l'Intégrité
 
13
  - **[QUEUES] Payload Sync** : S'assurer que les noms de champs dans `whatsappQueue.add` (producteur) matchent exactement le destructuring dans le worker (consommateur). Préférer `currentDay` partout pour la consistance.
14
  - **[DB] Enrollment ID** : Toujours passer l'ID d'inscription (`enrollmentId`) au job de feedback pour permettre la persistance des réponses sans crash Prisma.
15
  - **[JSON] Null Safety & Expansion** : Toujours vérifier la présence de données (Null Safety) lors de l'extension des schémas JSON, sous peine de briser le pipeline des jours précédents (Utiliser des guards `currentDay >= X`).
16
+ - **[FLOW] Re-validation Window** : Ne jamais bloquer une analyse entrante sous prétexte que le statut est COMPLETED si le délai depuis la dernière validation est inférieur à 5 minutes (cas de correction immédiate par l'utilisateur) ou si un nouvel élément multimédia est présent.
17
  - **[UX] Guidance Post-Validation** : Si un utilisateur envoie un message alors qu'il est en statut `COMPLETED`, le système ne doit pas rester muet. Il doit lui renvoyer un message de navigation (ex: "Tape SUITE pour continuer").
18
 
19
  ## 🛡️ Règle d'Or de l'Intégrité