CognxSafeTrack commited on
Commit
4967196
·
1 Parent(s): 8fde072

fix(ai): implement pedagogical leap fixes, pending_remediation, coherence locks and cache wipes

Browse files
apps/api/src/services/whatsapp.ts CHANGED
@@ -124,9 +124,19 @@ export class WhatsAppService {
124
  const { seedDatabase } = await import('@repo/database/seed');
125
  const result = await seedDatabase(prisma);
126
  console.log('[SEED] Result:', result.message);
 
 
 
 
 
 
 
 
 
 
127
  await scheduleMessage(user.id, result.seeded
128
- ? "✅ Seeding terminé ! Les 2 modules (FR + WOLOF) sont en base.\nEnvoie INSCRIPTION pour commencer."
129
- : "ℹ️ Les données existent déjà. Envoie INSCRIPTION pour commencer."
130
  );
131
  } catch (err: any) {
132
  console.error('[SEED] Error:', err.message);
@@ -181,7 +191,7 @@ export class WhatsAppService {
181
  } else if (action === 'CONTINUE') {
182
  // Determine if there is a pending exercise before advancing
183
  const pendingProgress = await prisma.userProgress.findFirst({
184
- where: { userId: user.id, exerciseStatus: 'PENDING' }
185
  });
186
  if (pendingProgress) {
187
  await scheduleMessage(user.id, user.language === 'WOLOF'
@@ -324,7 +334,7 @@ export class WhatsAppService {
324
 
325
  // Fallback to Exercise Response if nothing else matched
326
  const pendingProgress = await prisma.userProgress.findFirst({
327
- where: { userId: user.id, exerciseStatus: 'PENDING', trackId: activeEnrollment.trackId },
328
  });
329
 
330
  if (pendingProgress) {
 
124
  const { seedDatabase } = await import('@repo/database/seed');
125
  const result = await seedDatabase(prisma);
126
  console.log('[SEED] Result:', result.message);
127
+
128
+ // 🚨 COGNITIVE CACHE CLEAR: Delete old BusinessProfile contexts to prevent agricultural hallucinations
129
+ try {
130
+ await (prisma as any).businessProfile.deleteMany({ where: { userId: user.id } });
131
+ await prisma.user.update({ where: { id: user.id }, data: { activity: null } });
132
+ console.log(`[SEED] Cleared cognitive cache for User ${user.id}`);
133
+ } catch (cacheErr: any) {
134
+ console.error('[SEED] Failed to clear cognitive cache:', cacheErr.message);
135
+ }
136
+
137
  await scheduleMessage(user.id, result.seeded
138
+ ? "✅ Seeding terminé ! Le Cache Cognitif a été réinitialisé.\nEnvoie INSCRIPTION pour commencer."
139
+ : "ℹ️ Les données existent déjà. Cache Cognitif purgé. Envoie INSCRIPTION."
140
  );
141
  } catch (err: any) {
142
  console.error('[SEED] Error:', err.message);
 
191
  } else if (action === 'CONTINUE') {
192
  // Determine if there is a pending exercise before advancing
193
  const pendingProgress = await prisma.userProgress.findFirst({
194
+ where: { userId: user.id, exerciseStatus: { in: ['PENDING', 'PENDING_REMEDIATION'] } }
195
  });
196
  if (pendingProgress) {
197
  await scheduleMessage(user.id, user.language === 'WOLOF'
 
334
 
335
  // Fallback to Exercise Response if nothing else matched
336
  const pendingProgress = await prisma.userProgress.findFirst({
337
+ where: { userId: user.id, exerciseStatus: { in: ['PENDING', 'PENDING_REMEDIATION'] }, trackId: activeEnrollment.trackId },
338
  });
339
 
340
  if (pendingProgress) {
apps/whatsapp-worker/src/index.ts CHANGED
@@ -192,11 +192,11 @@ const worker = new Worker('whatsapp-queue', async (job: Job) => {
192
  nextDay = currentDay;
193
  }
194
 
195
- // 🚨 Hardening: If not qualified, we DO NOT award badges here
196
  await prisma.userProgress.update({
197
  where: { userId_trackId: { userId, trackId } },
198
  data: {
199
- exerciseStatus: 'PENDING', // Stay in pending for final success
200
  score: { increment: 0 }
201
  } as any
202
  });
 
192
  nextDay = currentDay;
193
  }
194
 
195
+ // 🚨 Hardening: If not qualified, we put the user in PENDING_REMEDIATION
196
  await prisma.userProgress.update({
197
  where: { userId_trackId: { userId, trackId } },
198
  data: {
199
+ exerciseStatus: 'PENDING_REMEDIATION', // Stay in remediation until final success
200
  score: { increment: 0 }
201
  } as any
202
  });
apps/whatsapp-worker/src/pedagogy.ts CHANGED
@@ -41,6 +41,17 @@ export async function sendLessonDay(userId: string, trackId: string, dayNumber:
41
  const activeEnrollment = user.enrollments[0];
42
  const trackTitle = activeEnrollment?.track?.title || (isWolof ? 'XAMLÉ' : 'XAMLÉ (FR)');
43
 
 
 
 
 
 
 
 
 
 
 
 
44
  const trackDay = await prisma.trackDay.findFirst({
45
  where: { trackId, dayNumber }
46
  });
 
41
  const activeEnrollment = user.enrollments[0];
42
  const trackTitle = activeEnrollment?.track?.title || (isWolof ? 'XAMLÉ' : 'XAMLÉ (FR)');
43
 
44
+ // 🚨 COHÉRENCE CHECK: Prevent jumps > 1 point
45
+ const currentDay = activeEnrollment?.currentDay || 1;
46
+ if (dayNumber - currentDay > 1) {
47
+ console.error(`[CRITICAL] Cohérence Error: User ${userId} attempting to jump from ${currentDay} to ${dayNumber} sans remédiation.`);
48
+ await sendTextMessage(user.phone, isWolof
49
+ ? "❌ Am na luy doxul ci sa njàng mi. Lëj-lëj la, dinañu ko lijjanti."
50
+ : "❌ Une erreur de synchronisation a été détectée sur ton parcours (Saut > 1). L'équipe technique a été notifiée."
51
+ );
52
+ return;
53
+ }
54
+
55
  const trackDay = await prisma.trackDay.findFirst({
56
  where: { trackId, dayNumber }
57
  });
packages/database/prisma/schema.prisma CHANGED
@@ -211,5 +211,6 @@ enum ExerciseType {
211
 
212
  enum ExerciseStatus {
213
  PENDING
 
214
  COMPLETED
215
  }
 
211
 
212
  enum ExerciseStatus {
213
  PENDING
214
+ PENDING_REMEDIATION
215
  COMPLETED
216
  }