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: {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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é
|