/** * Script pour ajouter des données démographiques de test aux utilisateurs existants */ import { pool } from '../db.js'; // Générer une date de naissance aléatoire dans une plage d'âge function randomDateOfBirth(minAge, maxAge) { const today = new Date(); const year = today.getFullYear() - Math.floor(Math.random() * (maxAge - minAge + 1)) - minAge; const month = Math.floor(Math.random() * 12); const day = Math.floor(Math.random() * 28) + 1; return new Date(year, month, day).toISOString().split('T')[0]; } // Liste de villes françaises pour les tests const cities = [ 'Paris', 'Lyon', 'Marseille', 'Toulouse', 'Nice', 'Nantes', 'Strasbourg', 'Montpellier', 'Bordeaux', 'Lille', 'Rennes', 'Reims', 'Le Havre', 'Saint-Étienne', 'Toulon' ]; // Liste de codes postaux correspondants const postalCodes = { 'Paris': ['75001', '75002', '75003', '75004', '75005'], 'Lyon': ['69001', '69002', '69003', '69004', '69005'], 'Marseille': ['13001', '13002', '13003', '13004', '13005'], 'Toulouse': ['31000', '31100', '31200', '31300', '31400'], 'Nice': ['06000', '06100', '06200', '06300'], 'Nantes': ['44000', '44100', '44200', '44300'], 'Strasbourg': ['67000', '67100', '67200'], 'Montpellier': ['34000', '34070', '34080', '34090'], 'Bordeaux': ['33000', '33100', '33200', '33300'], 'Lille': ['59000', '59160', '59260', '59777'], 'Rennes': ['35000', '35200', '35700'], 'Reims': ['51100', '51450', '51500'], 'Le Havre': ['76600', '76610', '76620'], 'Saint-Étienne': ['42000', '42100'], 'Toulon': ['83000', '83100', '83200'] }; async function addTestDemographics() { const client = await pool.connect(); try { console.log('🔄 Récupération des utilisateurs clients existants...'); // Récupérer tous les utilisateurs clients const users = await client.query(` SELECT id, email, city FROM users WHERE role = 'CLIENT' `); console.log(`📊 ${users.rows.length} utilisateurs clients trouvés`); if (users.rows.length === 0) { console.log('⚠️ Aucun utilisateur client trouvé. Aucune donnée démographique à ajouter.'); return; } console.log('🔄 Ajout des données démographiques...'); let updated = 0; for (const user of users.rows) { // Générer un genre aléatoire const genders = ['MALE', 'FEMALE', 'OTHER', 'NOT_SPECIFIED']; const weights = [45, 45, 5, 5]; // Distribution réaliste const randomGender = () => { const random = Math.random() * 100; let sum = 0; for (let i = 0; i < weights.length; i++) { sum += weights[i]; if (random <= sum) return genders[i]; } return 'NOT_SPECIFIED'; }; const gender = randomGender(); // Générer une date de naissance (âge entre 18 et 70 ans) const dateOfBirth = randomDateOfBirth(18, 70); // Sélectionner une ville aléatoire si l'utilisateur n'en a pas let city = user.city; let postalCode = null; if (!city || city.trim() === '') { city = cities[Math.floor(Math.random() * cities.length)]; const cityPostalCodes = postalCodes[city]; postalCode = cityPostalCodes[Math.floor(Math.random() * cityPostalCodes.length)]; } // Mettre à jour l'utilisateur const updateQuery = ` UPDATE users SET gender = $1, date_of_birth = $2, city = COALESCE(NULLIF(city, ''), $3), postal_code = COALESCE(NULLIF(postal_code, ''), $4) WHERE id = $5 `; await client.query(updateQuery, [gender, dateOfBirth, city, postalCode, user.id]); updated++; if (updated % 10 === 0) { process.stdout.write(`\r Mis à jour: ${updated}/${users.rows.length}`); } } console.log(`\n✅ ${updated} utilisateurs mis à jour avec succès !`); // Afficher un résumé des données console.log('\n📊 Résumé des données démographiques:'); const genderStats = await client.query(` SELECT gender, COUNT(*) as count FROM users WHERE role = 'CLIENT' GROUP BY gender ORDER BY count DESC `); console.log('\n Répartition par genre:'); genderStats.rows.forEach(row => { console.log(` - ${row.gender}: ${row.count}`); }); const ageStats = await client.query(` SELECT age_range as range, COUNT(*) as count FROM ( SELECT CASE WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, date_of_birth)) BETWEEN 18 AND 25 THEN '18-25' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, date_of_birth)) BETWEEN 26 AND 35 THEN '26-35' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, date_of_birth)) BETWEEN 36 AND 45 THEN '36-45' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, date_of_birth)) BETWEEN 46 AND 55 THEN '46-55' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, date_of_birth)) BETWEEN 56 AND 65 THEN '56-65' WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, date_of_birth)) > 65 THEN '65+' ELSE 'Non spécifié' END as age_range FROM users WHERE role = 'CLIENT' ) subquery GROUP BY age_range ORDER BY CASE age_range WHEN '18-25' THEN 1 WHEN '26-35' THEN 2 WHEN '36-45' THEN 3 WHEN '46-55' THEN 4 WHEN '56-65' THEN 5 WHEN '65+' THEN 6 ELSE 7 END `); console.log('\n Répartition par âge:'); ageStats.rows.forEach(row => { console.log(` - ${row.range}: ${row.count}`); }); const cityStats = await client.query(` SELECT city, COUNT(*) as count FROM users WHERE role = 'CLIENT' AND city IS NOT NULL GROUP BY city ORDER BY count DESC LIMIT 10 `); console.log('\n Top 10 villes:'); cityStats.rows.forEach((row, index) => { console.log(` ${index + 1}. ${row.city}: ${row.count}`); }); } catch (error) { console.error('❌ Erreur:', error.message); console.error(error); process.exit(1); } finally { client.release(); await pool.end(); } } addTestDemographics();