CognxSafeTrack commited on
Commit ·
26c5d48
1
Parent(s): c3ccb4c
chore: final logic hardening, AI prompt reinforcement and SUITE command fix
Browse files
apps/api/src/services/ai/index.ts
CHANGED
|
@@ -109,7 +109,8 @@ class AIService {
|
|
| 109 |
|
| 110 |
CONTRAINTES :
|
| 111 |
- LANGUE : "${userLanguage === 'WOLOF' ? 'WOLOF' : 'Français'}".
|
| 112 |
-
- ZÉRO ANGLAIS
|
|
|
|
| 113 |
- CONTEXTE : Ne cite jamais "Manga Deaf".
|
| 114 |
`;
|
| 115 |
|
|
@@ -145,7 +146,7 @@ class AIService {
|
|
| 145 |
RÈGLES :
|
| 146 |
1. Garde la valeur pédagogique EXACTEMENT la même.
|
| 147 |
2. Utilise des analogies, des exemples et un ton spécifiques au secteur "${userActivity}".
|
| 148 |
-
3. LANGUE : Réponds dans la langue d'origine de la leçon (${userLanguage === 'WOLOF' ? 'WOLOF' : 'Français'}). JAMAIS D'ANGLAIS.
|
| 149 |
4. STYLE : WhatsApp (gras, emojis). Direct, encourageant, pas trop long.
|
| 150 |
5. HALLUCINATION : Ne cite jamais "Manga Deaf". Si tu ne connais pas le secteur, reste neutre et professionnel.
|
| 151 |
|
|
|
|
| 109 |
|
| 110 |
CONTRAINTES :
|
| 111 |
- LANGUE : "${userLanguage === 'WOLOF' ? 'WOLOF' : 'Français'}".
|
| 112 |
+
- ZÉRO ANGLAIS (NEVER USE ENGLISH).
|
| 113 |
+
- ZÉRO HALLUCINATION (ne pas inventer de faits non cités).
|
| 114 |
- CONTEXTE : Ne cite jamais "Manga Deaf".
|
| 115 |
`;
|
| 116 |
|
|
|
|
| 146 |
RÈGLES :
|
| 147 |
1. Garde la valeur pédagogique EXACTEMENT la même.
|
| 148 |
2. Utilise des analogies, des exemples et un ton spécifiques au secteur "${userActivity}".
|
| 149 |
+
3. LANGUE : Réponds dans la langue d'origine de la leçon (${userLanguage === 'WOLOF' ? 'WOLOF' : 'Français'}). JAMAIS D'ANGLAIS (NEVER USE ENGLISH).
|
| 150 |
4. STYLE : WhatsApp (gras, emojis). Direct, encourageant, pas trop long.
|
| 151 |
5. HALLUCINATION : Ne cite jamais "Manga Deaf". Si tu ne connais pas le secteur, reste neutre et professionnel.
|
| 152 |
|
apps/api/src/services/whatsapp.ts
CHANGED
|
@@ -314,7 +314,9 @@ export class WhatsAppService {
|
|
| 314 |
// Handle accelerator "SUITE"
|
| 315 |
const isSuite = normalizedText === 'SUITE';
|
| 316 |
if (isSuite) {
|
| 317 |
-
const nextDay = activeEnrollment.currentDay
|
|
|
|
|
|
|
| 318 |
|
| 319 |
await prisma.enrollment.update({
|
| 320 |
where: { id: activeEnrollment.id },
|
|
|
|
| 314 |
// Handle accelerator "SUITE"
|
| 315 |
const isSuite = normalizedText === 'SUITE';
|
| 316 |
if (isSuite) {
|
| 317 |
+
const nextDay = activeEnrollment.currentDay % 1 !== 0
|
| 318 |
+
? Math.floor(activeEnrollment.currentDay) + 1
|
| 319 |
+
: activeEnrollment.currentDay + 1;
|
| 320 |
|
| 321 |
await prisma.enrollment.update({
|
| 322 |
where: { id: activeEnrollment.id },
|
apps/whatsapp-worker/src/index.ts
CHANGED
|
@@ -46,7 +46,7 @@ const worker = new Worker('whatsapp-queue', async (job: Job) => {
|
|
| 46 |
await sendTextMessage(phone, text);
|
| 47 |
}
|
| 48 |
else if (job.name === 'generate-feedback') {
|
| 49 |
-
const { userId, text, trackId, exercisePrompt, lessonText, exerciseCriteria,
|
| 50 |
const user = await prisma.user.findUnique({
|
| 51 |
where: { id: userId },
|
| 52 |
include: { businessProfile: true } as any
|
|
@@ -149,7 +149,9 @@ const worker = new Worker('whatsapp-queue', async (job: Job) => {
|
|
| 149 |
|
| 150 |
// 🌟 Adaptive Pedagogy: Dynamic Remediation Logic v1.0 🌟
|
| 151 |
let nextDay = currentDay + 1;
|
| 152 |
-
const currentProgress = await prisma.userProgress.findUnique({
|
|
|
|
|
|
|
| 153 |
const currentBadges = ((currentProgress as any)?.badges as string[]) || [];
|
| 154 |
let updatedBadges = [...currentBadges];
|
| 155 |
|
|
@@ -162,6 +164,15 @@ const worker = new Worker('whatsapp-queue', async (job: Job) => {
|
|
| 162 |
console.log(`[WORKER] Exercise not qualified but no remediation day defined. Staying on Day ${currentDay}.`);
|
| 163 |
nextDay = currentDay;
|
| 164 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 165 |
} else {
|
| 166 |
// Success! Award Badges & Mark Completed
|
| 167 |
const trackDayBadges = (trackDay as any)?.badges as string[] || [];
|
|
@@ -170,7 +181,7 @@ const worker = new Worker('whatsapp-queue', async (job: Job) => {
|
|
| 170 |
}
|
| 171 |
|
| 172 |
await prisma.userProgress.update({
|
| 173 |
-
where: {
|
| 174 |
data: {
|
| 175 |
exerciseStatus: 'COMPLETED',
|
| 176 |
score: { increment: 1 },
|
|
|
|
| 46 |
await sendTextMessage(phone, text);
|
| 47 |
}
|
| 48 |
else if (job.name === 'generate-feedback') {
|
| 49 |
+
const { userId, text, trackId, exercisePrompt, lessonText, exerciseCriteria, currentDay, totalDays, language } = job.data;
|
| 50 |
const user = await prisma.user.findUnique({
|
| 51 |
where: { id: userId },
|
| 52 |
include: { businessProfile: true } as any
|
|
|
|
| 149 |
|
| 150 |
// 🌟 Adaptive Pedagogy: Dynamic Remediation Logic v1.0 🌟
|
| 151 |
let nextDay = currentDay + 1;
|
| 152 |
+
const currentProgress = await prisma.userProgress.findUnique({
|
| 153 |
+
where: { userId_trackId: { userId, trackId } }
|
| 154 |
+
});
|
| 155 |
const currentBadges = ((currentProgress as any)?.badges as string[]) || [];
|
| 156 |
let updatedBadges = [...currentBadges];
|
| 157 |
|
|
|
|
| 164 |
console.log(`[WORKER] Exercise not qualified but no remediation day defined. Staying on Day ${currentDay}.`);
|
| 165 |
nextDay = currentDay;
|
| 166 |
}
|
| 167 |
+
|
| 168 |
+
// 🚨 Hardening: If not qualified, we DO NOT award badges here
|
| 169 |
+
await prisma.userProgress.update({
|
| 170 |
+
where: { userId_trackId: { userId, trackId } },
|
| 171 |
+
data: {
|
| 172 |
+
exerciseStatus: 'PENDING', // Stay in pending for final success
|
| 173 |
+
score: { increment: 0 }
|
| 174 |
+
} as any
|
| 175 |
+
});
|
| 176 |
} else {
|
| 177 |
// Success! Award Badges & Mark Completed
|
| 178 |
const trackDayBadges = (trackDay as any)?.badges as string[] || [];
|
|
|
|
| 181 |
}
|
| 182 |
|
| 183 |
await prisma.userProgress.update({
|
| 184 |
+
where: { userId_trackId: { userId, trackId } },
|
| 185 |
data: {
|
| 186 |
exerciseStatus: 'COMPLETED',
|
| 187 |
score: { increment: 1 },
|