user nouveau onglet

This commit is contained in:
Biqoz
2025-11-16 01:34:01 +01:00
parent 0d95eca1ee
commit ad575641a1
16 changed files with 1033 additions and 33 deletions

114
scripts/README.md Normal file
View File

@@ -0,0 +1,114 @@
# 📥 Import Automatique d'Utilisateurs depuis Excel
Ce script permet d'importer automatiquement des utilisateurs dans MongoDB depuis un fichier Excel.
## 🚀 Utilisation
### 1. Préparer le fichier Excel
Placer votre fichier `.xlsx` dans le dossier `public/list_users/`
**Format attendu :**
```
Nom Etudiant | Prénom Etudiant | Matricule HE | EMail Etudiant 2
```
**Exemple :**
```
Albarran Perez | Tamara | 1240935 | tamara.albarran@student.ihecs.be
Amjahed | Kawtar | 1241004 | kawtar.amjahed@student.ihecs.be
```
**Nom du fichier :** Le nom doit être le nom du référent avec underscores.
-`Emmanuel_WATHELE.xlsx`
-`Sophie_MARTIN.xlsx`
-`liste.xlsx`
### 2. Configurer le script
Ouvrir `scripts/import-users.js` et modifier ces lignes :
```javascript
const XLSX_FILENAME = "Emmanuel_WATHELE.xlsx"; // ⚠️ Nom du fichier
const DEFAULT_PASSWORD = "IHECS-2025"; // Mot de passe par défaut
const COURS = "Ouverture à l'esprit critique"; // Nom du cours
```
### 3. Lancer l'import
```bash
node scripts/import-users.js
```
## 📊 Ce que fait le script
1. ✅ Lit le fichier Excel
2. ✅ Extrait le référent depuis le nom du fichier (`Emmanuel_WATHELE``Emmanuel WATHELE`)
3. ✅ Hash le mot de passe une seule fois (optimisation)
4. ✅ Pour chaque étudiant :
- Vérifie que l'email est valide
- Vérifie que l'email n'existe pas déjà
- Crée l'utilisateur avec :
- `nom`, `prenom`, `email`
- `referent` (extrait du nom du fichier)
- `cours` (défini dans le script)
- `password` hashé
- `role: "USER"`
- Crée une balance initiale (3 000 000 tokens)
5. ✅ Affiche un résumé détaillé
## 📝 Exemple de résultat
```
🚀 Démarrage de l'import...
📋 Référent: Emmanuel WATHELE
📚 Cours: Ouverture à l'esprit critique
🔑 Password par défaut: IHECS-2025
📁 Lecture du fichier: C:\...\public\list_users\Emmanuel_WATHELE.xlsx
✅ 50 lignes détectées dans le fichier
🔐 Hash du mot de passe...
🔌 Connexion à MongoDB...
✅ Connecté à MongoDB
📥 Import en cours...
[1/50] ✅ Créé: Tamara Albarran Perez (tamara.albarran@student.ihecs.be)
[2/50] ✅ Créé: Kawtar Amjahed (kawtar.amjahed@student.ihecs.be)
[3/50] ⏭️ Ignoré (existe déjà): nezaket.arslan@student.ihecs.be
...
============================================================
📊 RÉSUMÉ DE L'IMPORT
============================================================
✅ Utilisateurs créés: 48
⏭️ Utilisateurs ignorés (déjà existants): 2
❌ Erreurs: 0
============================================================
✨ Import terminé !
```
## ⚠️ Important
- Le script **ignore** les utilisateurs déjà existants (même email)
- Le script **ignore** la colonne "Matricule HE" (non sauvegardée)
- Tous les utilisateurs auront le **même mot de passe** (ils pourront le changer après)
- Chaque utilisateur reçoit **3 000 000 tokens** par défaut
## 🔧 Dépannage
**Erreur : "Cannot find module 'xlsx'"**
```bash
npm install xlsx
```
**Erreur : "connect ECONNREFUSED"**
- Vérifier que MongoDB est démarré
- Vérifier la connexion dans `.env.local`
**Erreur : "File not found"**
- Vérifier que le fichier est bien dans `public/list_users/`
- Vérifier le nom du fichier dans le script

167
scripts/import-ihecs.js Normal file
View File

@@ -0,0 +1,167 @@
import XLSX from 'xlsx';
import { MongoClient, ObjectId } from 'mongodb';
import bcrypt from 'bcryptjs';
import path from 'path';
import { fileURLToPath } from 'url';
import dotenv from 'dotenv';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Charger les variables d'environnement depuis .env.local
dotenv.config({ path: path.join(__dirname, '..', '.env.local') });
// Configuration
const MONGODB_URI = process.env.MONGODB_URI;
const XLSX_FILENAME = "IHECS.xlsx"; // ⚠️ Fichier pour IHECS / M2RP
const DEFAULT_PASSWORD = "IHECS-2025";
const REFERENT = "IHECS";
const COURS = "M2RP";
async function importUsers() {
console.log("🚀 Démarrage de l'import IHECS / M2RP...\n");
try {
// Vérifier que MONGODB_URI est défini
if (!MONGODB_URI) {
throw new Error("MONGODB_URI non défini dans .env.local");
}
console.log(`📋 Référent: ${REFERENT}`);
console.log(`📚 Cours: ${COURS}`);
console.log(`🔑 Password par défaut: ${DEFAULT_PASSWORD}\n`);
// Lire le fichier Excel
const filePath = path.join(__dirname, '..', 'public', 'list_users', XLSX_FILENAME);
console.log(`📁 Lecture du fichier: ${filePath}`);
const workbook = XLSX.readFile(filePath);
const sheet = workbook.Sheets[workbook.SheetNames[0]];
const data = XLSX.utils.sheet_to_json(sheet);
console.log(`${data.length} lignes détectées dans le fichier\n`);
// Hash le password une seule fois (optimisation)
console.log("🔐 Hash du mot de passe...");
const hashedPassword = await bcrypt.hash(DEFAULT_PASSWORD, 12);
// Préparer les users
const users = data.map(row => ({
nom: row["Nom de famille"],
prenom: row["Prénom"],
name: `${row["Prénom"]} ${row["Nom de famille"]}`,
email: row["Adresse de courriel"],
username: row["Nom d'utilisateur"] || row["Adresse de courriel"]?.split("@")[0],
password: hashedPassword,
emailVerified: false,
avatar: null,
provider: "local",
role: "USER",
// Nouveaux champs pour le cours et le référent
referent: REFERENT,
cours: COURS,
plugins: [],
twoFactorEnabled: false,
termsAccepted: true,
personalization: {
memories: false,
_id: new ObjectId(),
},
backupCodes: [],
refreshToken: [],
createdAt: new Date(),
updatedAt: new Date(),
__v: 0,
}));
// Connexion à MongoDB
console.log("🔌 Connexion à MongoDB...");
const client = new MongoClient(MONGODB_URI);
await client.connect();
const db = client.db('librechat');
console.log("✅ Connecté à MongoDB\n");
// Import des users
const results = { created: [], errors: [], skipped: [] };
console.log("📥 Import en cours...\n");
for (let i = 0; i < users.length; i++) {
const user = users[i];
const progress = `[${i + 1}/${users.length}]`;
try {
// Validation email
if (!user.email || !user.email.includes('@')) {
console.log(`${progress} ⚠️ Email invalide: ${user.name}`);
results.errors.push({ name: user.name, error: "Email invalide" });
continue;
}
// Vérifier si email existe déjà
const existing = await db.collection("users").findOne({ email: user.email });
if (existing) {
console.log(`${progress} ⏭️ Ignoré (existe déjà): ${user.email}`);
results.skipped.push(user.email);
continue;
}
// Insérer le user
const result = await db.collection("users").insertOne(user);
// Créer la balance initiale
await db.collection("balances").insertOne({
user: result.insertedId,
tokenCredits: 3000000,
autoRefillEnabled: false,
lastRefill: new Date(),
refillAmount: 0,
refillIntervalUnit: "month",
refillIntervalValue: 1,
__v: 0,
});
console.log(`${progress} ✅ Créé: ${user.prenom} ${user.nom} (${user.email})`);
results.created.push(user.email);
} catch (error) {
console.error(`${progress} ❌ Erreur: ${user.email} - ${error.message}`);
results.errors.push({ email: user.email, error: error.message });
}
}
// Fermer la connexion
await client.close();
// Résumé final
console.log("\n" + "=".repeat(60));
console.log("📊 RÉSUMÉ DE L'IMPORT - IHECS / M2RP");
console.log("=".repeat(60));
console.log(`✅ Utilisateurs créés: ${results.created.length}`);
console.log(`⏭️ Utilisateurs ignorés (déjà existants): ${results.skipped.length}`);
console.log(`❌ Erreurs: ${results.errors.length}`);
console.log("=".repeat(60));
if (results.errors.length > 0) {
console.log("\n⚠ DÉTAIL DES ERREURS:");
results.errors.forEach(e => {
console.log(` - ${e.email || e.name}: ${e.error}`);
});
}
console.log("\n✨ Import terminé !\n");
} catch (error) {
console.error("\n❌ ERREUR FATALE:", error.message);
console.error(error);
process.exit(1);
}
process.exit(0);
}
// Lancer l'import
importUsers();

168
scripts/import-users.js Normal file
View File

@@ -0,0 +1,168 @@
import XLSX from 'xlsx';
import { MongoClient, ObjectId } from 'mongodb';
import bcrypt from 'bcryptjs';
import path from 'path';
import { fileURLToPath } from 'url';
import dotenv from 'dotenv';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Charger les variables d'environnement depuis .env.local
dotenv.config({ path: path.join(__dirname, '..', '.env.local') });
// Configuration
const MONGODB_URI = process.env.MONGODB_URI;
const XLSX_FILENAME = "Emmanuel_WATHELE.xlsx"; // ⚠️ À modifier selon le fichier
const DEFAULT_PASSWORD = "IHECS-2025";
const COURS = "Ouverture à l'esprit critique";
async function importUsers() {
console.log("🚀 Démarrage de l'import...\n");
try {
// Vérifier que MONGODB_URI est défini
if (!MONGODB_URI) {
throw new Error("MONGODB_URI non défini dans .env.local");
}
// 1. Extraire le référent depuis le nom du fichier
const referent = XLSX_FILENAME.replace('.xlsx', '').replace(/_/g, ' ');
console.log(`📋 Référent: ${referent}`);
console.log(`📚 Cours: ${COURS}`);
console.log(`🔑 Password par défaut: ${DEFAULT_PASSWORD}\n`);
// 2. Lire le fichier Excel
const filePath = path.join(__dirname, '..', 'public', 'list_users', XLSX_FILENAME);
console.log(`📁 Lecture du fichier: ${filePath}`);
const workbook = XLSX.readFile(filePath);
const sheet = workbook.Sheets[workbook.SheetNames[0]];
const data = XLSX.utils.sheet_to_json(sheet);
console.log(`${data.length} lignes détectées dans le fichier\n`);
// 3. Hash le password une seule fois (optimisation)
console.log("🔐 Hash du mot de passe...");
const hashedPassword = await bcrypt.hash(DEFAULT_PASSWORD, 12);
// 4. Préparer les users
const users = data.map(row => ({
nom: row["Nom Etudiant"],
prenom: row["Prénom Etudiant"],
name: `${row["Prénom Etudiant"]} ${row["Nom Etudiant"]}`,
email: row["EMail Etudiant 2"],
username: row["EMail Etudiant 2"]?.split("@")[0],
password: hashedPassword,
emailVerified: false,
avatar: null,
provider: "local",
role: "USER",
// Nouveaux champs pour le cours et le référent
referent: referent,
cours: COURS,
plugins: [],
twoFactorEnabled: false,
termsAccepted: true,
personalization: {
memories: false,
_id: new ObjectId(),
},
backupCodes: [],
refreshToken: [],
createdAt: new Date(),
updatedAt: new Date(),
__v: 0,
}));
// 5. Connexion à MongoDB
console.log("🔌 Connexion à MongoDB...");
const client = new MongoClient(MONGODB_URI);
await client.connect();
const db = client.db('librechat');
console.log("✅ Connecté à MongoDB\n");
// 6. Import des users
const results = { created: [], errors: [], skipped: [] };
console.log("📥 Import en cours...\n");
for (let i = 0; i < users.length; i++) {
const user = users[i];
const progress = `[${i + 1}/${users.length}]`;
try {
// Validation email
if (!user.email || !user.email.includes('@')) {
console.log(`${progress} ⚠️ Email invalide: ${user.name}`);
results.errors.push({ name: user.name, error: "Email invalide" });
continue;
}
// Vérifier si email existe déjà
const existing = await db.collection("users").findOne({ email: user.email });
if (existing) {
console.log(`${progress} ⏭️ Ignoré (existe déjà): ${user.email}`);
results.skipped.push(user.email);
continue;
}
// Insérer le user
const result = await db.collection("users").insertOne(user);
// Créer la balance initiale
await db.collection("balances").insertOne({
user: result.insertedId,
tokenCredits: 3000000,
autoRefillEnabled: false,
lastRefill: new Date(),
refillAmount: 0,
refillIntervalUnit: "month",
refillIntervalValue: 1,
__v: 0,
});
console.log(`${progress} ✅ Créé: ${user.prenom} ${user.nom} (${user.email})`);
results.created.push(user.email);
} catch (error) {
console.error(`${progress} ❌ Erreur: ${user.email} - ${error.message}`);
results.errors.push({ email: user.email, error: error.message });
}
}
// 7. Fermer la connexion
await client.close();
// 8. Résumé final
console.log("\n" + "=".repeat(60));
console.log("📊 RÉSUMÉ DE L'IMPORT");
console.log("=".repeat(60));
console.log(`✅ Utilisateurs créés: ${results.created.length}`);
console.log(`⏭️ Utilisateurs ignorés (déjà existants): ${results.skipped.length}`);
console.log(`❌ Erreurs: ${results.errors.length}`);
console.log("=".repeat(60));
if (results.errors.length > 0) {
console.log("\n⚠ DÉTAIL DES ERREURS:");
results.errors.forEach(e => {
console.log(` - ${e.email || e.name}: ${e.error}`);
});
}
console.log("\n✨ Import terminé !\n");
} catch (error) {
console.error("\n❌ ERREUR FATALE:", error.message);
console.error(error);
process.exit(1);
}
process.exit(0);
}
// Lancer l'import
importUsers();