CognxSafeTrack commited on
Commit
cd75882
·
1 Parent(s): af32fee

feat(module1): integrate the 12-day curriculum in FR/WO with seed data and auto-routing

Browse files
apps/api/src/services/whatsapp.ts CHANGED
@@ -18,12 +18,36 @@ export class WhatsAppService {
18
  console.log('New user created, asked for language.');
19
  return;
20
  } else {
21
- // Not registered yet, hasn't typed INSCRIPTION. We ignore or prompt:
22
  console.log(`Unregistered user ${phone} sent a message. Need INSCRIPTION.`);
23
  return;
24
  }
25
  }
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  // 1.5. Check Pending Pedagogy Exercise
28
  const pendingProgress = await prisma.userProgress.findFirst({
29
  where: { userId: user.id, exerciseStatus: 'PENDING' },
@@ -114,9 +138,13 @@ export class WhatsAppService {
114
 
115
  await scheduleMessage(user.id, welcomeMsg);
116
 
117
- // Find default track
 
 
 
 
118
  const defaultTrack = await prisma.track.findFirst({
119
- where: { title: "Business Model Express" } // Assuming this exists from seed
120
  });
121
 
122
  if (defaultTrack) {
 
18
  console.log('New user created, asked for language.');
19
  return;
20
  } else {
 
21
  console.log(`Unregistered user ${phone} sent a message. Need INSCRIPTION.`);
22
  return;
23
  }
24
  }
25
 
26
+ // 1.5. Testing / Cheat Codes (Only for registered users)
27
+ if (normalizedText === 'INSCRIPTION') {
28
+ await prisma.enrollment.deleteMany({ where: { userId: user.id } });
29
+ await prisma.userProgress.deleteMany({ where: { userId: user.id } });
30
+ user = await prisma.user.update({
31
+ where: { id: user.id },
32
+ data: { city: null, activity: null }
33
+ });
34
+ await scheduleMessage(user.id, "Réinitialisation réussie. Choisissez votre langue :\n1. Français 🇫🇷\n2. Wolof 🇸🇳");
35
+ return;
36
+ }
37
+
38
+ if (normalizedText === 'SEED') {
39
+ await scheduleMessage(user.id, "🔄 Lancement du seeding en cours...");
40
+ try {
41
+ const { execSync } = require('child_process');
42
+ execSync('npx tsx ../../packages/database/seed.ts', { stdio: 'inherit' });
43
+ await scheduleMessage(user.id, "✅ Seeding terminé avec succès !");
44
+ } catch (err: any) {
45
+ console.error('Seed Error:', err);
46
+ await scheduleMessage(user.id, `❌ Erreur de seed : ${err.message}`);
47
+ }
48
+ return;
49
+ }
50
+
51
  // 1.5. Check Pending Pedagogy Exercise
52
  const pendingProgress = await prisma.userProgress.findFirst({
53
  where: { userId: user.id, exerciseStatus: 'PENDING' },
 
138
 
139
  await scheduleMessage(user.id, welcomeMsg);
140
 
141
+ // Find default track based on language
142
+ const trackTitle = user.language === 'FR'
143
+ ? "Comprendre Son Business (FR)"
144
+ : "Comprendre Son Business (WOLOF)";
145
+
146
  const defaultTrack = await prisma.track.findFirst({
147
+ where: { title: trackTitle }
148
  });
149
 
150
  if (defaultTrack) {
docs/flow utilisateurs et formation .md ADDED
@@ -0,0 +1,641 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # XAMLE – NOUVELLE ARCHITECTURE PÉDAGOGIQUE VOIX & WHATSAPP
2
+
3
+ > Objectif : transformer Xamle en plateforme EdTech mobile-first ultra intuitive pour le secteur informel, priorisant AUDIO + BOUTONS WHATSAPP + EXERCICES TERRAIN + IA.
4
+
5
+ ---
6
+
7
+ # 1️⃣ POSITIONNEMENT PÉDAGOGIQUE STRATÉGIQUE
8
+
9
+ Xamle ne doit pas être un simple bot qui envoie des messages.
10
+
11
+ Il doit devenir :
12
+
13
+ → Un coach business vocal interactif
14
+ → Un système d’apprentissage terrain progressif
15
+ → Un moteur IA qui transforme apprentissage → documents concrets
16
+
17
+ Cible : entrepreneurs secteur informel
18
+ Contraintes :
19
+ - Faible écriture
20
+ - Connexion instable
21
+ - Temps limité
22
+ - Préférence audio
23
+
24
+ Donc priorité :
25
+
26
+ ✅ Audio court
27
+ ✅ Boutons interactifs
28
+ ✅ Exercices terrain concrets
29
+ ✅ Réponses vocales possibles
30
+ ✅ Vidéo courte mobile verticale
31
+
32
+ ---
33
+
34
+ # 2️⃣ NOUVEAU FLOW UTILISATEUR APRÈS INSCRIPTION
35
+
36
+ ## Étape 1 – Choix langue
37
+
38
+ 1. Français 🇫🇷
39
+ 2. Wolof 🇸🇳
40
+
41
+ ## Étape 2 – Choix OBJECTIF PRINCIPAL (UX simplifiée)
42
+
43
+ 🎯 Trouver des clients
44
+ 💰 Mieux gagner de l’argent
45
+ 🧠 Comprendre son business
46
+ 🚀 Lever des fonds / Pitcher
47
+
48
+ ➡ IMPORTANT : Ces choix restent visibles côté utilisateur (langage simple et concret).
49
+
50
+ ⚙️ MAIS en backend, chaque objectif correspond à de vrais modules structurés :
51
+
52
+ - "Trouver des clients" → Module Marketing + Validation terrain (Design Thinking appliqué)
53
+ - "Mieux gagner de l’argent" → Module Pricing + Business Model
54
+ - "Comprendre son business" → Module Business Model Simplifié
55
+ - "Lever des fonds / Pitcher" → Module Pitch + Pitch Deck
56
+
57
+ 👉 Conclusion :
58
+ On garde les choix orientés PROBLÈME (UX simple)
59
+ Mais on structure les contenus avec de vrais modules entrepreneuriaux (Design Thinking, Business Model, Pitch).
60
+
61
+ ---
62
+
63
+ # 3️⃣ STRUCTURE DES MODULES D’APPRENTISSAGE (VERSION MVP SANS VIDÉO)
64
+
65
+ ⚠️ Décision :
66
+ Pour la V1, on n’intègre PAS encore les vidéos.
67
+ On se concentre sur : AUDIO + BOUTONS + EXERCICE + FEEDBACK IA.
68
+ Les vidéos seront ajoutées en V2.
69
+
70
+ Chaque module contient :
71
+
72
+ 1️⃣ Leçon audio (2–3 min max)
73
+ - langage simple
74
+ - voix naturelle locale
75
+ - 1 seul objectif par leçon
76
+ - stockée sur R2
77
+
78
+ 2️⃣ Exercice terrain obligatoire
79
+ Exemples :
80
+ - Parler à 3 clients
81
+ - Calculer son prix réel
82
+ - Observer un problème
83
+ - Faire un mini pitch audio
84
+
85
+ 3️⃣ Interaction WhatsApp
86
+ - Boutons interactifs
87
+ - Validation par chiffre possible
88
+ - Message vocal accepté
89
+
90
+ 4️⃣ Feedback IA
91
+ - Encouragement
92
+ - Correction simple
93
+ - Suggestion pratique
94
+ - Génération automatique si nécessaire
95
+
96
+ ---
97
+
98
+ Architecture logique d’une journée :
99
+
100
+ Étape 1 → sendLessonDay()
101
+ Étape 2 → envoi audio
102
+ Étape 3 → envoi boutons
103
+ Étape 4 → attente réponse utilisateur
104
+ Étape 5 → sauvegarde DB
105
+ Étape 6 → feedback IA
106
+ Étape 7 → déblocage jour suivant
107
+
108
+
109
+ ---
110
+
111
+ # 4️⃣ STRUCTURE PROGRESSIVE DES MODULES (STRUCTURE HYBRIDE RECOMMANDÉE)
112
+
113
+ ⚠️ Décision stratégique :
114
+
115
+ On ne doit PAS opposer :
116
+ - Objectifs simples (Trouver clients, Gagner argent…)
117
+ - Modules structurés (Design Thinking, Business Model, Pitch)
118
+
119
+ On combine les deux.
120
+
121
+ ---
122
+
123
+ ## NIVEAU 1 – MODULES VISIBLES (Langage simple UX)
124
+
125
+ Ce que l’utilisateur voit :
126
+
127
+ 1️⃣ Comprendre son business
128
+ 2️⃣ Trouver des clients
129
+ 3️⃣ Mieux gagner de l’argent
130
+ 4️⃣ Structurer son activité
131
+ 5️⃣ Pitcher son projet
132
+
133
+ ---
134
+
135
+ ## NIVEAU 2 – STRUCTURE ACADÉMIQUE INTERNE (Backend)
136
+
137
+ Ces modules sont en réalité construits sur :
138
+
139
+ ### MODULE A – Design Thinking Terrain
140
+ - Observer problème
141
+ - Tester solution
142
+ - Ajuster
143
+
144
+ ### MODULE B – Business Model Simplifié
145
+ - Client
146
+ - Proposition de valeur
147
+ - Revenus
148
+ - Coûts
149
+ - Partenaires
150
+
151
+ ### MODULE C – Pricing & Rentabilité
152
+ - Coût réel
153
+ - Marge
154
+ - Prix stratégique
155
+
156
+ ### MODULE D – Marketing Terrain
157
+ - Où trouver clients
158
+ - Message simple
159
+ - Test terrain
160
+
161
+ ### MODULE E – Pitch Simple
162
+ - Problème
163
+ - Solution
164
+ - Client
165
+ - Différence
166
+
167
+ ### MODULE F – Pitch Deck (avancé)
168
+ - Histoire
169
+ - Marché
170
+ - Traction
171
+ - Besoin financier
172
+
173
+ ---
174
+
175
+ ## Progression pédagogique recommandée
176
+
177
+ Phase 1 – Survie & Cash
178
+ → Comprendre business
179
+ → Trouver clients
180
+ → Fixer prix
181
+
182
+ Phase 2 – Structuration
183
+ → Business Model
184
+ → Marketing terrain
185
+
186
+ Phase 3 – Croissance
187
+ → Pitch
188
+ → Pitch deck
189
+
190
+ ---
191
+
192
+ 🎯 Conclusion stratégique :
193
+
194
+ UX = langage problème (simple)
195
+ Architecture = vrais frameworks entrepreneuriaux
196
+
197
+ C’est la meilleure combinaison entre accessibilité et crédibilité.
198
+
199
+ ---
200
+
201
+ # 5️⃣ UX WHATSAPP RECOMMANDÉE
202
+
203
+ Après chaque leçon :
204
+
205
+ 1️⃣ Réécouter 🎧
206
+ 2️⃣ Voir vidéo ▶️
207
+ 3️⃣ Faire exercice 📝
208
+ 4️⃣ Continuer ➡️
209
+
210
+ Réponses possibles :
211
+ - Boutons interactifs
212
+ - Message vocal
213
+ - Chiffre (1/2/3/4)
214
+
215
+ ---
216
+
217
+ # 6️⃣ ADAPTATION BASE DE DONNÉES RECOMMANDÉE
218
+
219
+ Nouvelle structure recommandée pour track_days :
220
+
221
+ - id
222
+ - track_id
223
+ - day_number
224
+ - title
225
+ - audio_url
226
+ - video_url
227
+ - lesson_text
228
+ - exercise_type (audio / texte / photo / bouton)
229
+ - exercise_prompt
230
+ - validation_keyword
231
+ - buttons_json
232
+
233
+ Ajouter :
234
+
235
+ - user_progress (score, last_activity)
236
+ - media_storage_url
237
+ - exercise_status
238
+
239
+ ---
240
+
241
+ # 7️⃣ FAISABILITÉ TECHNIQUE AVEC INFRA ACTUELLE
242
+
243
+ Infra actuelle :
244
+
245
+ ✅ Neon Postgres
246
+ ✅ Railway Worker
247
+ ✅ Redis Upstash
248
+ ✅ R2 Cloudflare
249
+ ✅ WhatsApp Cloud API
250
+
251
+ Conclusion :
252
+
253
+ ✔ Audio sortant = possible
254
+ ✔ Boutons interactifs = possible
255
+ ✔ Messages vocaux entrants = possible
256
+ ✔ Vidéos = possible
257
+ ✔ Stockage média = possible via R2
258
+
259
+ Aucun changement d’infrastructure nécessaire.
260
+
261
+ Le blocage n’est pas technique.
262
+ Il est pédagogique et UX.
263
+
264
+ ---
265
+
266
+ # 8️⃣ CE QUE L’HUMAIN DOIT DÉFINIR
267
+
268
+ 1️⃣ Scripts audio simples (langue locale validée)
269
+ 2️⃣ Exercices terrain réels
270
+ 3️⃣ Progression pédagogique cohérente
271
+ 4️⃣ Vocabulaire accessible secteur informel
272
+
273
+ ---
274
+
275
+ # 9️⃣ PROMPT À DONNER À ANTIGRAVITY POUR INTÉGRATION RAILWAY + BACKEND
276
+
277
+ Utilise le prompt ci-dessous :
278
+
279
+ ---
280
+
281
+ Tu es architecte senior Node.js + Prisma + WhatsApp Cloud API.
282
+
283
+ Contexte :
284
+ Nous transformons le WhatsApp Worker actuel en moteur pédagogique interactif vocal (sans vidéo pour la V1).
285
+
286
+ Stack existante :
287
+ - Node.js
288
+ - Prisma + Neon Postgres
289
+ - Redis Upstash
290
+ - Railway
291
+ - R2 Cloudflare
292
+ - WhatsApp Cloud API
293
+
294
+ ⚠️ Ne pas modifier l’architecture globale.
295
+ ⚠️ Ne pas supprimer le système actuel d’onboarding.
296
+ ⚠️ Ajouter uniquement la couche pédagogique.
297
+
298
+ ---
299
+
300
+ OBJECTIFS TECHNIQUES
301
+
302
+ 1️⃣ Adapter le modèle Prisma :
303
+
304
+ Model TrackDay {
305
+ id
306
+ trackId
307
+ dayNumber
308
+ title
309
+ audioUrl
310
+ lessonText
311
+ exerciseType
312
+ exercisePrompt
313
+ validationKeyword
314
+ buttonsJson
315
+ unlockCondition
316
+ }
317
+
318
+ Créer table UserProgress :
319
+
320
+ Model UserProgress {
321
+ id
322
+ userId
323
+ trackId
324
+ currentDay
325
+ score
326
+ lastInteraction
327
+ exerciseStatus
328
+ }
329
+
330
+ ---
331
+
332
+ 2️⃣ Créer fonction principale :
333
+
334
+ async function sendLessonDay(userId: string, dayNumber: number)
335
+
336
+ Elle doit :
337
+ - Charger TrackDay
338
+ - Envoyer audio WhatsApp
339
+ - Envoyer message interactif avec boutons
340
+ - Sauvegarder état progression
341
+
342
+ ---
343
+
344
+ 3️⃣ Modifier Webhook WhatsApp
345
+
346
+ Le webhook doit :
347
+ - Détecter message texte
348
+ - Détecter message vocal
349
+ - Détecter bouton interactif
350
+ - Mapper réponse vers exercice
351
+ - Sauvegarder réponse
352
+ - Déclencher feedback IA
353
+
354
+ ---
355
+
356
+ 4️⃣ Gestion des exercices
357
+
358
+ Si exerciseType = "audio"
359
+ → Télécharger media WhatsApp
360
+ → Stocker sur R2
361
+ → Sauvegarder URL
362
+
363
+ Si exerciseType = "text"
364
+ → Sauvegarder texte
365
+
366
+ Si exerciseType = "button"
367
+ → Mapper reply.id
368
+
369
+ ---
370
+
371
+ 5️⃣ Feedback IA
372
+
373
+ Créer fonction :
374
+
375
+ async function generateFeedback(userInput, context)
376
+
377
+ Utiliser OPENAI_API_KEY existante
378
+ Retourner feedback court (max 5 lignes)
379
+
380
+ ---
381
+
382
+ 6️⃣ Scoring
383
+
384
+ - +1 point par exercice validé
385
+ - Mise à jour UserProgress
386
+ - Si dernier jour → trigger génération document (pitch / onepager)
387
+
388
+ ---
389
+
390
+ Livrables attendus :
391
+
392
+ - Schéma Prisma complet
393
+ - Migration SQL
394
+ - Exemple JSON bouton WhatsApp
395
+ - Code complet sendLessonDay()
396
+ - Code webhook mis à jour
397
+ - Plan de migration base existante
398
+
399
+ ---
400
+
401
+ IMPORTANT :
402
+
403
+ Ne pas ajouter vidéo pour la V1.
404
+ Concentrer la logique sur audio + interaction + progression.
405
+
406
+ ---
407
+
408
+ Retourner le code prêt à intégrer sur Railway.
409
+
410
+ ---
411
+
412
+
413
+ ---
414
+
415
+ # 🔟 MON AVIS STRATÉGIQUE
416
+
417
+ Ce que vous avez fait jusqu’ici est faisable.
418
+
419
+ L’infrastructure est solide.
420
+
421
+ Le vrai chantier maintenant est :
422
+
423
+ ➡ UX pédagogique
424
+ ➡ Structuration des modules
425
+ ➡ Interaction intuitive
426
+
427
+ La proposition "Voix + Boutons + Terrain" est excellente.
428
+
429
+ C’est différenciant.
430
+ C’est adapté au secteur informel.
431
+ C’est scalable.
432
+
433
+ Et surtout : c’est réaliste techniquement avec votre stack actuelle.
434
+
435
+ ---
436
+
437
+ # 🚀 PROCHAINE ÉTAPE RECOMMANDÉE
438
+
439
+ Décision : programme de 1 mois (4 semaines) avec terrain.
440
+
441
+ Pour la V1 WhatsApp, on recommande :
442
+ - 3 leçons / semaine (lun-mer-ven) → 12 leçons / mois
443
+ - Chaque leçon : audio 2–3 min + 1 exercice terrain + 1 réponse simple
444
+ - Les jours "OFF" : l’apprenant applique sur le terrain (sans surcharge)
445
+
446
+ ✅ Objectif : apprentissage réel + action terrain + progression mesurable.
447
+
448
+ ---
449
+
450
+ # 11️⃣ MODULE 1 (1 MOIS) – COMPRENDRE SON BUSINESS (SECTEUR INFORMEL)
451
+
452
+ ## 11.1 Résultat attendu à la fin du mois
453
+
454
+ À la fin du Module 1, l’apprenant doit pouvoir :
455
+ - Décrire son activité en 1 phrase (simple)
456
+ - Identifier 1 client principal + où le trouver
457
+ - Expliquer le problème client qu’il résout
458
+ - Énoncer son offre (produit/service) clairement
459
+ - Donner un prix de base cohérent (premier test)
460
+ - Construire un mini pitch vocal de 30–45 secondes
461
+
462
+ ⚠️ Ce module n’est pas théorique : chaque semaine impose des tests terrain.
463
+
464
+ ---
465
+
466
+ ## 11.2 Règles UX WhatsApp (V1)
467
+
468
+ - Réponses autorisées :
469
+ - 1/2/3/4 (chiffres)
470
+ - audio (recommandé)
471
+ - texte très court
472
+ - Longs formulaires interdits.
473
+ - Toujours proposer des choix via boutons quand possible.
474
+
475
+ ### Boutons standard (après chaque leçon)
476
+ 1️⃣ Réécouter 🎧
477
+ 2️⃣ Faire l’exercice 📝
478
+ 3️⃣ Envoyer ma réponse 🎙️
479
+ 4️⃣ Continuer ➡️
480
+
481
+ ---
482
+
483
+ ## 11.3 Structure d’une leçon (TrackDay)
484
+
485
+ Chaque TrackDay doit contenir :
486
+ - title
487
+ - audioUrl (R2)
488
+ - lessonText (résumé très court)
489
+ - exercisePrompt (terrain)
490
+ - exerciseType (audio|text|button|photo)
491
+ - buttonsJson (interactive)
492
+ - validationKeyword (ex: FAIT, OK, DONE) + acceptation audio
493
+ - unlockCondition (complétion jour)
494
+
495
+ ---
496
+
497
+ ## 11.4 Calendrier – 4 semaines / 12 leçons
498
+
499
+ > Note : l’apprenant reçoit la leçon le matin (ex: 08:00) mais peut répondre quand il veut.
500
+
501
+ ### Semaine 1 – Clarifier l’activité (ce que je fais vraiment)
502
+
503
+ **Jour 1 (Lun) – "Mon activité en 1 phrase"**
504
+ - Objectif : clarifier ce que tu vends (sans jargon)
505
+ - Audio (script FR – simple) :
506
+ - "Dis-moi simplement : tu aides QUI à faire QUOI, et comment tu gagnes de l’argent. Exemple : Je vends du jus bissap aux étudiants devant l’université."
507
+ - Exercice terrain : écrire ou dire une phrase :
508
+ - "Je vends [offre] à [client] à [lieu]" (ou audio)
509
+ - Réponse attendue : audio 10–20s (ou texte 1 ligne)
510
+ - Feedback IA : reformule en phrase plus claire
511
+
512
+ **Jour 2 (Mer) – "Ce que le client achète vraiment"**
513
+ - Objectif : différencier produit vs bénéfice
514
+ - Audio :
515
+ - "Le client n’achète pas un produit, il achète un résultat. Exemple : il n’achète pas du savon, il achète la propreté."
516
+ - Exercice terrain : demander à 2 clients :
517
+ - "Pourquoi tu achètes ça ?" → noter 2 réponses
518
+ - Réponse : 1 audio (20s) avec les 2 raisons
519
+ - Feedback IA : extrait 1 bénéfice principal
520
+
521
+ **Jour 3 (Ven) – "Mon client principal"**
522
+ - Objectif : choisir un client prioritaire (pas "tout le monde")
523
+ - Audio :
524
+ - "Si tu essaies de vendre à tout le monde, tu vends à personne. On choisit 1 client principal."
525
+ - Exercice : choisir 1 client principal parmi 3 options (boutons)
526
+ - A) Jeunes
527
+ - B) Femmes
528
+ - C) Commerçants
529
+ - D) Autre (texte court)
530
+ - Réponse : bouton + (si Autre) texte
531
+ - Feedback IA : confirme le persona simple
532
+
533
+ ### Semaine 2 – Problème client (ce que je résous)
534
+
535
+ **Jour 4 (Lun) – "Le problème n°1"**
536
+ - Objectif : identifier 1 douleur forte
537
+ - Audio : "Quel problème ton client veut éviter ?"
538
+ - Exercice terrain : parler à 3 personnes du client choisi et demander :
539
+ - "C’est quoi ton plus gros problème sur ça ?"
540
+ - Réponse : audio 30s résumant les 3 réponses
541
+ - Feedback IA : synthèse en 1 problème
542
+
543
+ **Jour 5 (Mer) – "Quand le problème arrive"**
544
+ - Objectif : comprendre contexte et moment
545
+ - Audio : "À quel moment ton client a le problème ?"
546
+ - Exercice : choisir un moment (boutons)
547
+ - Matin / Midi / Soir / Tout le temps
548
+ - Réponse : bouton + 1 phrase (option)
549
+ - Feedback IA : propose une phrase de positionnement
550
+
551
+ **Jour 6 (Ven) – "Comment ils le résolvent aujourd’hui"**
552
+ - Objectif : concurrence = solutions actuelles
553
+ - Audio : "Avant toi, le client fait comment ?"
554
+ - Exercice : écrire 2 solutions actuelles (texte court) ou audio
555
+ - Feedback IA : clarifie ton avantage
556
+
557
+ ### Semaine 3 – Offre (solution) & preuve terrain
558
+
559
+ **Jour 7 (Lun) – "Mon offre simple"**
560
+ - Objectif : décrire l’offre en mots simples
561
+ - Audio : "Dis ta solution en une phrase."
562
+ - Exercice : phrase offre + 1 exemple réel
563
+ - Réponse : audio 20s
564
+ - Feedback IA : reformule en offre claire
565
+
566
+ **Jour 8 (Mer) – "Promesse et limite"**
567
+ - Objectif : éviter promesses irréalistes
568
+ - Audio : "Promets petit, livre grand."
569
+ - Exercice : choisir 1 promesse parmi 3 (boutons)
570
+ - Rapide / Moins cher / Plus fiable
571
+ - Feedback IA : propose promesse adaptée au contexte
572
+
573
+ **Jour 9 (Ven) – "Test terrain 1"**
574
+ - Objectif : valider l’intérêt
575
+ - Audio : "Parle à 5 personnes et propose ton offre en 10 secondes."
576
+ - Exercice :
577
+ - Dire à 5 personnes : "Je fais X pour Y"
578
+ - Noter combien disent OUI/NON
579
+ - Réponse : chiffre (ex: OUI=2, NON=3)
580
+ - Feedback IA : conseil pratique (améliorer phrase)
581
+
582
+ ### Semaine 4 – Argent (premier prix) & mini pitch
583
+
584
+ **Jour 10 (Lun) – "Prix de base"**
585
+ - Objectif : fixer un premier prix cohérent
586
+ - Audio : "Ton prix doit couvrir tes coûts + marge."
587
+ - Exercice :
588
+ - écrire 2 coûts principaux + prix actuel
589
+ - Réponse : texte court (ou audio)
590
+ - Feedback IA : suggère marge minimale
591
+
592
+ **Jour 11 (Mer) – "Ton avantage"**
593
+ - Objectif : différenciation simple
594
+ - Audio : "Pourquoi toi plutôt qu’un autre ?"
595
+ - Exercice : choisir 1 avantage (boutons)
596
+ - Qualité / Rapidité / Confiance / Proximité
597
+ - Feedback IA : phrase d’avantage
598
+
599
+ **Jour 12 (Ven) – "Mini pitch audio"**
600
+ - Objectif : sortir un pitch 30–45s
601
+ - Audio : guide pitch :
602
+ 1) Je suis…
603
+ 2) J’aide…
604
+ 3) Parce que…
605
+ 4) Je vends… à …
606
+ - Exercice : envoyer pitch vocal 30–45s
607
+ - Réponse : audio obligatoire
608
+ - Feedback IA : 3 conseils max + version texte du pitch
609
+
610
+ ---
611
+
612
+ ## 11.5 Sorties IA après Module 1 (automatiques)
613
+
614
+ Après Jour 12 complété :
615
+ - Générer :
616
+ - Pitch texte 30s
617
+ - One-liner activité
618
+ - Mini fiche (1 page) "Mon activité" (option)
619
+
620
+ ⚠️ Pitch deck complet = V2 (ou Module Pitch dédié).
621
+
622
+ ---
623
+
624
+ ## 11.6 Notes d’implémentation (pour Antigravity)
625
+
626
+ - Créer Track "MODULE1_COMPRENDRE_BUSINESS" (FR + WO)
627
+ - Seeder : insérer 12 TrackDays
628
+ - sendLessonDay() :
629
+ - envoyer audio (media)
630
+ - envoyer interactive buttons
631
+ - Webhook :
632
+ - accepter chiffres + boutons + audio
633
+ - Exercice terrain :
634
+ - validationKeyword = {"FAIT","OK","DONE"} ou audio reçu
635
+ - Progression :
636
+ - currentDay++ après validation
637
+
638
+ ---
639
+
640
+ Fin du document.
641
+
packages/database/seed.ts CHANGED
@@ -3,44 +3,219 @@ import { PrismaClient } from '@prisma/client';
3
  const prisma = new PrismaClient();
4
 
5
  async function main() {
6
- // 1. Business Model Track (7 days)
7
- const businessTrack = await prisma.track.create({
8
  data: {
9
- title: "Business Model Express",
10
- description: "Structurez votre projet en 7 jours",
11
- duration: 7,
12
  language: "FR",
13
  days: {
14
  create: [
15
- { dayNumber: 1, exerciseType: "TEXT", lessonText: "Bienvenue ! Jour 1: Quel est le problème que vous résolvez ? Répondez par un court message." },
16
- { dayNumber: 2, exerciseType: "TEXT", lessonText: "Jour 2: Qui est votre client idéal ? (Age, métier, localisation)" },
17
- { dayNumber: 3, exerciseType: "TEXT", lessonText: "Jour 3: Quelle est votre solution en une phrase simple ?" },
18
- { dayNumber: 4, exerciseType: "TEXT", lessonText: "Jour 4: Comment gagnez-vous de l'argent ? (Prix, abonnement, marge)" },
19
- { dayNumber: 5, exerciseType: "TEXT", lessonText: "Jour 5: Quels sont vos coûts principaux ?" },
20
- { dayNumber: 6, exerciseType: "TEXT", lessonText: "Jour 6: Avez-vous déjà vendu ? Donnez un chiffre (CA ou nombre de clients)." },
21
- { dayNumber: 7, exerciseType: "TEXT", lessonText: "Jour 7: Félicitations ! Envoyez 'PITCH' pour générer votre mini-document." }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  ]
23
  }
24
  }
25
  });
26
 
27
- // 2. Pitch Track (7 days)
28
- const pitchTrack = await prisma.track.create({
29
  data: {
30
- title: "Pitch Master",
31
- description: "Apprenez à convaincre en 30 secondes",
32
- duration: 7,
33
- language: "FR",
34
  days: {
35
  create: [
36
- { dayNumber: 1, exerciseType: "TEXT", lessonText: "Jour 1: L'accroche. Comment capter l'attention en 5 secondes ?" },
37
- // ... more days
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  ]
39
  }
40
  }
41
  });
42
 
43
- console.log({ businessTrack, pitchTrack });
44
  }
45
 
46
  main()
 
3
  const prisma = new PrismaClient();
4
 
5
  async function main() {
6
+ // 1. Module 1: Comprendre Son Business (FR)
7
+ const comprendreBusinessFR = await prisma.track.create({
8
  data: {
9
+ title: "Comprendre Son Business (FR)",
10
+ description: "Apprenez à définir, tester et vendre votre projet en 12 leçons.",
11
+ duration: 12,
12
  language: "FR",
13
  days: {
14
  create: [
15
+ {
16
+ dayNumber: 1,
17
+ exerciseType: "AUDIO",
18
+ lessonText: "Aujourd’hui, on commence simple. Beaucoup de personnes disent : je fais le commerce. Mais ça ne veut rien dire. Dis-moi clairement : Tu aides QUI, à faire QUOI, et comment tu gagnes de largent. Exemple : Je vends du jus bissap aux étudiants devant l’université. Maintenant, c’est à toi. Dis ta phrase en 15 secondes.",
19
+ exercisePrompt: "Envoie-moi un court message vocal (ou texte) avec ta phrase d'activité :"
20
+ },
21
+ {
22
+ dayNumber: 2,
23
+ exerciseType: "AUDIO",
24
+ lessonText: "Le client n’achète pas ton produit. Il achète un résultat. Il n’achète pas du savon. Il achète la propreté. Va demander à 2 clients : Pourquoi tu achètes ça ? Écoute bien leurs mots.",
25
+ exercisePrompt: "Envoie un audio résumant les 2 réponses de tes clients."
26
+ },
27
+ {
28
+ dayNumber: 3,
29
+ exerciseType: "BUTTON",
30
+ lessonText: "Si tu vends à tout le monde, tu ne vends à personne. Choisis un seul client principal. Qui est le plus intéressé par ton produit ?",
31
+ exercisePrompt: "Sélectionne ton client principal ci-dessous :",
32
+ buttonsJson: [
33
+ { id: "jeunes", title: "Jeunes" },
34
+ { id: "femmes", title: "Femmes" },
35
+ { id: "commercants", title: "Commerçants" }
36
+ ]
37
+ },
38
+ {
39
+ dayNumber: 4,
40
+ exerciseType: "TEXT",
41
+ lessonText: "Ton client a un problème. Quel est son plus grand problème ? Parle à 3 personnes aujourd’hui. Pose cette question. Écoute sans expliquer ton produit.",
42
+ exercisePrompt: "Quel est le problème N°1 que tes clients t'ont partagé ?"
43
+ },
44
+ {
45
+ dayNumber: 5,
46
+ exerciseType: "BUTTON",
47
+ lessonText: "À quel moment ton client a ce problème ?",
48
+ exercisePrompt: "Choisis le moment d'apparition du problème :",
49
+ buttonsJson: [
50
+ { id: "matin_midi", title: "Matin ou Midi" },
51
+ { id: "soir", title: "Le Soir" },
52
+ { id: "tout_le_temps", title: "Tout le temps" }
53
+ ]
54
+ },
55
+ {
56
+ dayNumber: 6,
57
+ exerciseType: "TEXT",
58
+ lessonText: "Avant toi, il faisait comment ?",
59
+ exercisePrompt: "Donne-moi 2 solutions que ton client utilisait avant de te connaître :"
60
+ },
61
+ {
62
+ dayNumber: 7,
63
+ exerciseType: "TEXT",
64
+ lessonText: "Explique ta solution en mots simples. Pas compliqué.",
65
+ exercisePrompt: "Décris-moi ton offre très simplement en une phrase :"
66
+ },
67
+ {
68
+ dayNumber: 8,
69
+ exerciseType: "BUTTON",
70
+ lessonText: "Tu ne peux pas promettre tout. Choisis une seule force.",
71
+ exercisePrompt: "Quelle est ta promesse principale ?",
72
+ buttonsJson: [
73
+ { id: "rapide", title: "Rapide" },
74
+ { id: "moins_cher", title: "Moins cher" },
75
+ { id: "fiable_proche", title: "Fiable / Proche" }
76
+ ]
77
+ },
78
+ {
79
+ dayNumber: 9,
80
+ exerciseType: "TEXT",
81
+ lessonText: "Parle à 5 personnes. Dis ta phrase. Combien disent OUI ?",
82
+ exercisePrompt: "Combien t'ont dit OUI ? (Envoie juste un chiffre)"
83
+ },
84
+ {
85
+ dayNumber: 10,
86
+ exerciseType: "TEXT",
87
+ lessonText: "Ton prix doit couvrir tes coûts. Note 2 dépenses importantes.",
88
+ exercisePrompt: "Quelles sont tes 2 plus grosses dépenses pour ce projet ?"
89
+ },
90
+ {
91
+ dayNumber: 11,
92
+ exerciseType: "BUTTON",
93
+ lessonText: "Pourquoi toi et pas un autre ?",
94
+ exercisePrompt: "Quel est ton vrai avantage concurrentiel ?",
95
+ buttonsJson: [
96
+ { id: "qualite", title: "Qualité" },
97
+ { id: "rapidite", title: "Rapidité" },
98
+ { id: "confiance", title: "Confiance" }
99
+ ]
100
+ },
101
+ {
102
+ dayNumber: 12,
103
+ exerciseType: "AUDIO",
104
+ lessonText: "Maintenant tu es prêt. Dis en 30 secondes : Je suis... J’aide... Parce que... Je vends... À...",
105
+ exercisePrompt: "C'est l'heure du test ! Envoie-moi un audio avec ton Mini Pitch de 30 secondes :"
106
+ }
107
  ]
108
  }
109
  }
110
  });
111
 
112
+ // 2. Module 1: Comprendre Son Business (WOLOF)
113
+ const comprendreBusinessWO = await prisma.track.create({
114
  data: {
115
+ title: "Comprendre Son Business (WOLOF)",
116
+ description: "Apprenez à définir, tester et vendre votre projet en 12 leçons.",
117
+ duration: 12,
118
+ language: "WOLOF",
119
  days: {
120
  create: [
121
+ {
122
+ dayNumber: 1,
123
+ exerciseType: "AUDIO",
124
+ lessonText: "Tey, danuy tàmbalee ak lu yomb. Nit ñu bari dañuy wax : dama def commerce. Waaye loolu amul solo. Wax ma leer : Yaay jàppalé KAN, mu def LAN, te naka nga amee xaalis. Misaal : Damaa jaay jus bissap ci taalibe yu université. Léegi sa waxtu la. Wax sa activité ci 15 seconde.",
125
+ exercisePrompt: "Yónnee ma ab kàddu (audio) walla message bu gatt ngir wax sa mbir :"
126
+ },
127
+ {
128
+ dayNumber: 2,
129
+ exerciseType: "AUDIO",
130
+ lessonText: "Kiliifa bi du jënd sa produit rek. Mu jënd ab résultat. Du jënd savon rek. Mu jënd set. Dem laaj 2 kiliifa : Lu tax nga jënd lii ? Déggal bu baax li ñuy wax.",
131
+ exercisePrompt: "Yónnee ma audio ngir tënk ñaari tontu ya."
132
+ },
133
+ {
134
+ dayNumber: 3,
135
+ exerciseType: "BUTTON",
136
+ lessonText: "Su nga jaay ci ñépp, doo jaay ci kenn. Tànnal benn kiliifa bu mag. Kan moo gën a soxla sa produit ?",
137
+ exercisePrompt: "Tànnal sa kiliifa bu mag ci suuf :",
138
+ buttonsJson: [
139
+ { id: "ndaw_nyi", title: "Ndaw ñi / Jeunes" },
140
+ { id: "jigeen_nyi", title: "Jigeen ñi / Femmes" },
141
+ { id: "jaaykat_yi", title: "Jaaykat yi / Comms" }
142
+ ]
143
+ },
144
+ {
145
+ dayNumber: 4,
146
+ exerciseType: "TEXT",
147
+ lessonText: "Sa kiliifa am na jafe jafe. Lan mooy jafe jafe bu gën a rëy ? Dem waxtaan ak 3 nit. Laaj leen. Bul def publicité.",
148
+ exercisePrompt: "Lan mooy jafe jafe bu gën a mag bi sa kiliifa yi am ?"
149
+ },
150
+ {
151
+ dayNumber: 5,
152
+ exerciseType: "BUTTON",
153
+ lessonText: "Kañ la jafe jafe bi di ñëw ?",
154
+ exercisePrompt: "Tànnal jamono ji jafe jafe bi di faral di am :",
155
+ buttonsJson: [
156
+ { id: "suba_bëccëg", title: "Suba walla Bëccëg" },
157
+ { id: "ngoon", title: "Ngoon / Guddi" },
158
+ { id: "saa_su_ne", title: "Saa su nekk" }
159
+ ]
160
+ },
161
+ {
162
+ dayNumber: 6,
163
+ exerciseType: "TEXT",
164
+ lessonText: "Balaa yaw, naka la daan def ?",
165
+ exercisePrompt: "Wax ma ñaari pexe yi kiliifa bi daan jëfandikoo balaa xam sa produit :"
166
+ },
167
+ {
168
+ dayNumber: 7,
169
+ exerciseType: "TEXT",
170
+ lessonText: "Wax sa solution ci wax yu yomb.",
171
+ exercisePrompt: "Tënkal sa solution ci benn phrase bu yomb :"
172
+ },
173
+ {
174
+ dayNumber: 8,
175
+ exerciseType: "BUTTON",
176
+ lessonText: "Bul promettre lépp. Tànnal benn doole.",
177
+ exercisePrompt: "Lan mooy sa dige bu mag ?",
178
+ buttonsJson: [
179
+ { id: "gaaw", title: "Dafa gaaw" },
180
+ { id: "yomb", title: "Dafa yomb / Prix" },
181
+ { id: "woor", title: "Dafa woor" }
182
+ ]
183
+ },
184
+ {
185
+ dayNumber: 9,
186
+ exerciseType: "TEXT",
187
+ lessonText: "Dem waxtaan ak 5 nit. Ñaata ñu wax WAAN ?",
188
+ exercisePrompt: "Ñaata nit ñoo wax WAAN ? (Bind ma chiffre bi rek)"
189
+ },
190
+ {
191
+ dayNumber: 10,
192
+ exerciseType: "TEXT",
193
+ lessonText: "Sa priix war na japp sa dépense. Bind ñaari dépense.",
194
+ exercisePrompt: "Bind ma ñaari dépense yu gën a rëy ci sa mbir :"
195
+ },
196
+ {
197
+ dayNumber: 11,
198
+ exerciseType: "BUTTON",
199
+ lessonText: "Lu tax yaw te du keneen ?",
200
+ exercisePrompt: "Lan nga gën a mën ci ñeneen ñi ?",
201
+ buttonsJson: [
202
+ { id: "baax", title: "Dafa baax" },
203
+ { id: "gaaw", title: "Dafa gaaw" },
204
+ { id: "koolute", title: "Kooluté / Confiance" }
205
+ ]
206
+ },
207
+ {
208
+ dayNumber: 12,
209
+ exerciseType: "AUDIO",
210
+ lessonText: "Léegi nga hazır. Wax ci 30 seconde : Man ma... Damaa jàppalé... Ndax... Damaa jaay... Ci... Yónnee sa audio.",
211
+ exercisePrompt: "Yónnee ma sa Pitch bu gatt ci 30 seconde :"
212
+ }
213
  ]
214
  }
215
  }
216
  });
217
 
218
+ console.log({ comprendreBusinessFR, comprendreBusinessWO });
219
  }
220
 
221
  main()