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 +31 -3
- docs/flow utilisateurs et formation .md +641 -0
- packages/database/seed.ts +196 -21
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:
|
| 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.
|
| 7 |
-
const
|
| 8 |
data: {
|
| 9 |
-
title: "
|
| 10 |
-
description: "
|
| 11 |
-
duration:
|
| 12 |
language: "FR",
|
| 13 |
days: {
|
| 14 |
create: [
|
| 15 |
-
{
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
]
|
| 23 |
}
|
| 24 |
}
|
| 25 |
});
|
| 26 |
|
| 27 |
-
// 2.
|
| 28 |
-
const
|
| 29 |
data: {
|
| 30 |
-
title: "
|
| 31 |
-
description: "Apprenez à
|
| 32 |
-
duration:
|
| 33 |
-
language: "
|
| 34 |
days: {
|
| 35 |
create: [
|
| 36 |
-
{
|
| 37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
]
|
| 39 |
}
|
| 40 |
}
|
| 41 |
});
|
| 42 |
|
| 43 |
-
console.log({
|
| 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 l’argent. 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()
|