CognxSafeTrack commited on
Commit
8cd83e2
·
1 Parent(s): b150436

refactor(prod): unify currentDay exclusively in Enrollment model to fix scheduler sync

Browse files
apps/api/src/services/whatsapp.ts CHANGED
@@ -95,17 +95,26 @@ export class WhatsAppService {
95
  // CONTINUE → fall through to SUITE logic below
96
  }
97
 
98
- // 1.5. Check Pending Pedagogy Exercise
99
  const pendingProgress = await prisma.userProgress.findFirst({
100
  where: { userId: user.id, exerciseStatus: 'PENDING' },
101
  include: { track: true }
102
  });
103
 
104
  if (pendingProgress) {
105
- console.log(`User ${user.id} responding to exercise for Track ${pendingProgress.trackId} Day ${pendingProgress.currentDay}`);
 
 
 
 
 
 
 
 
 
106
 
107
  const trackDay = await prisma.trackDay.findFirst({
108
- where: { trackId: pendingProgress.trackId, dayNumber: pendingProgress.currentDay }
109
  });
110
 
111
  if (trackDay) {
@@ -157,12 +166,13 @@ export class WhatsAppService {
157
 
158
  // Advance to next day or mark complete
159
  const totalDays = pendingProgress.track.duration;
160
- if (pendingProgress.currentDay >= totalDays) {
161
  await scheduleMessage(user.id, user.language === 'WOLOF'
162
  ? "🎉 Baraka Allahu fik ! Jeex nga module bi. Dokumaan yi dinañu leen yónnee ci kanam !"
163
  : "🎉 Félicitations ! Vous avez terminé ce module. Vos documents intelligents arrivent bientôt !"
164
  );
165
- await scheduleTrackDay(user.id, pendingProgress.trackId, pendingProgress.currentDay + 1);
 
166
  } else {
167
  await scheduleMessage(user.id, user.language === 'WOLOF'
168
  ? "Baax na ! Yónnee *SUITE* ngir dem ci kanam."
 
95
  // CONTINUE → fall through to SUITE logic below
96
  }
97
 
98
+ // 2. Check Pending Exercise (User Progress)
99
  const pendingProgress = await prisma.userProgress.findFirst({
100
  where: { userId: user.id, exerciseStatus: 'PENDING' },
101
  include: { track: true }
102
  });
103
 
104
  if (pendingProgress) {
105
+ const enrollment = await prisma.enrollment.findFirst({
106
+ where: { userId: user.id, trackId: pendingProgress.trackId, status: 'ACTIVE' }
107
+ });
108
+
109
+ if (!enrollment) {
110
+ console.warn(`[WHATSAPP] User ${user.id} has PENDING exercise but no ACTIVE enrollment on Track ${pendingProgress.trackId}`);
111
+ return;
112
+ }
113
+
114
+ console.log(`User ${user.id} responding to exercise for Track ${pendingProgress.trackId} Day ${enrollment.currentDay}`);
115
 
116
  const trackDay = await prisma.trackDay.findFirst({
117
+ where: { trackId: pendingProgress.trackId, dayNumber: enrollment.currentDay }
118
  });
119
 
120
  if (trackDay) {
 
166
 
167
  // Advance to next day or mark complete
168
  const totalDays = pendingProgress.track.duration;
169
+ if (enrollment.currentDay >= totalDays) {
170
  await scheduleMessage(user.id, user.language === 'WOLOF'
171
  ? "🎉 Baraka Allahu fik ! Jeex nga module bi. Dokumaan yi dinañu leen yónnee ci kanam !"
172
  : "🎉 Félicitations ! Vous avez terminé ce module. Vos documents intelligents arrivent bientôt !"
173
  );
174
+ // Technically it's complete, so passing currentDay + 1 triggers the scheduleTrackDay mark completion logic
175
+ await scheduleTrackDay(user.id, pendingProgress.trackId, enrollment.currentDay + 1);
176
  } else {
177
  await scheduleMessage(user.id, user.language === 'WOLOF'
178
  ? "Baax na ! Yónnee *SUITE* ngir dem ci kanam."
apps/whatsapp-worker/src/pedagogy.ts CHANGED
@@ -124,17 +124,21 @@ export async function sendLessonDay(userId: string, trackId: string, dayNumber:
124
  await prisma.userProgress.upsert({
125
  where: { userId_trackId: { userId, trackId } },
126
  update: {
127
- currentDay: dayNumber,
128
  exerciseStatus: 'PENDING',
129
  lastInteraction: new Date()
130
  },
131
  create: {
132
  userId,
133
  trackId,
134
- currentDay: dayNumber,
135
  exerciseStatus: 'PENDING'
136
  }
137
  });
138
 
 
 
 
 
 
 
139
  console.log(`[PEDAGOGY] Lesson Day ${dayNumber} sent. UserProgress set to PENDING.`);
140
  }
 
124
  await prisma.userProgress.upsert({
125
  where: { userId_trackId: { userId, trackId } },
126
  update: {
 
127
  exerciseStatus: 'PENDING',
128
  lastInteraction: new Date()
129
  },
130
  create: {
131
  userId,
132
  trackId,
 
133
  exerciseStatus: 'PENDING'
134
  }
135
  });
136
 
137
+ // 🌟 5. Correctly update Enrollment.currentDay (Fixes Scheduler Bug) 🌟
138
+ await prisma.enrollment.updateMany({
139
+ where: { userId, trackId, status: 'ACTIVE' },
140
+ data: { currentDay: dayNumber }
141
+ });
142
+
143
  console.log(`[PEDAGOGY] Lesson Day ${dayNumber} sent. UserProgress set to PENDING.`);
144
  }
packages/database/prisma/schema.prisma CHANGED
@@ -68,7 +68,6 @@ model UserProgress {
68
  id String @id @default(uuid())
69
  userId String
70
  trackId String
71
- currentDay Int @default(1)
72
  score Int @default(0)
73
  lastInteraction DateTime @default(now())
74
  exerciseStatus ExerciseStatus @default(PENDING)
 
68
  id String @id @default(uuid())
69
  userId String
70
  trackId String
 
71
  score Int @default(0)
72
  lastInteraction DateTime @default(now())
73
  exerciseStatus ExerciseStatus @default(PENDING)
packages/database/sync-days.ts ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { PrismaClient } from '@prisma/client';
2
+
3
+ const prisma = new PrismaClient();
4
+
5
+ async function syncDays() {
6
+ console.log('🔄 Démarrage de la synchronisation des jours (UserProgress -> Enrollment)...');
7
+
8
+ const enrollments = await prisma.enrollment.findMany({
9
+ where: { status: 'ACTIVE' },
10
+ include: { user: { include: { progress: true } } }
11
+ });
12
+
13
+ let updatedCount = 0;
14
+
15
+ for (const enrollment of enrollments) {
16
+ // Find the corresponding UserProgress for this active track
17
+ const progress = enrollment.user.progress.find(p => p.trackId === enrollment.trackId);
18
+
19
+ if (progress) {
20
+ // If UserProgress has a higher internal currentDay than Enrollment,
21
+ // the scheduler bug affected this user. We need to align Enrollment.
22
+ // (Note: Since we haven't removed currentDay from UserProgress yet, we can access it via 'any')
23
+ const progressAny = progress as any;
24
+ if (progressAny.currentDay && progressAny.currentDay > enrollment.currentDay) {
25
+ console.log(`➡️ Mise à jour: User ${enrollment.userId} Track ${enrollment.trackId}: Jour ${enrollment.currentDay} -> ${progressAny.currentDay}`);
26
+
27
+ await prisma.enrollment.update({
28
+ where: { id: enrollment.id },
29
+ data: { currentDay: progressAny.currentDay }
30
+ });
31
+ updatedCount++;
32
+ }
33
+ }
34
+ }
35
+
36
+ console.log(`✅ Synchronisation terminée. ${updatedCount} inscriptions synchronisées.`);
37
+ }
38
+
39
+ syncDays()
40
+ .catch(console.error)
41
+ .finally(() => prisma.$disconnect());