import { pool } from '../db.js'; const TOTAL_TICKETS = 500000; const BATCH_SIZE = 1000; const PRIZE_DISTRIBUTION = { 'INFUSEUR': { percentage: 0.60, name: 'Infuseur à thé' }, 'THE_GRATUIT': { percentage: 0.20, name: 'Thé détox/infusion 100g' }, 'THE_SIGNATURE': { percentage: 0.10, name: 'Thé signature 100g' }, 'COFFRET_DECOUVERTE': { percentage: 0.06, name: 'Coffret découverte 39€' }, 'COFFRET_PRESTIGE': { percentage: 0.04, name: 'Coffret prestige 69€' } }; const generateCode = () => { // Format: TT + 8 caractères alphanumériques mélangés (ex: TT11BA22KO) // Mélange de chiffres et lettres de manière aléatoire const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; const digits = '0123456789'; const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; let code = 'TT'; // Générer 8 caractères alphanumériques mélangés for (let i = 0; i < 8; i++) { const randomChar = chars[Math.floor(Math.random() * chars.length)]; code += randomChar; } return code; }; const generateTickets = async () => { try { console.log('🎫 Génération de 500,000 tickets Thé Tip Top\n'); const prizesResult = await pool.query('SELECT id, name, type FROM prizes'); const prizes = {}; prizesResult.rows.forEach(p => prizes[p.type] = p); const distribution = {}; let total = 0; console.log('📊 DISTRIBUTION:'); for (const [type, config] of Object.entries(PRIZE_DISTRIBUTION)) { const count = Math.floor(TOTAL_TICKETS * config.percentage); distribution[type] = count; total += count; const percent = (config.percentage * 100).toFixed(0); const countStr = count.toLocaleString('fr-FR'); console.log(` • ${percent}% - ${countStr} tickets - ${config.name}`); } if (total < TOTAL_TICKETS) { const diff = TOTAL_TICKETS - total; distribution.infuseur += diff; console.log(`\n⚙️ Ajustement: +${diff} tickets ajoutés aux infuseurs`); } const existing = await pool.query('SELECT COUNT(*) FROM tickets'); if (parseInt(existing.rows[0].count) > 0) { console.log('\n⚠️ Suppression des anciens tickets...'); await pool.query('DELETE FROM tickets'); console.log('✅ Anciens tickets supprimés'); } console.log('\n🚀 Génération en cours...\n'); let generated = 0; const start = Date.now(); for (const [type, count] of Object.entries(distribution)) { const prize = prizes[type]; if (!prize) { console.log(`⚠️ Lot "${type}" introuvable, ignoré`); continue; } const prizeCountStr = count.toLocaleString('fr-FR'); console.log(`📦 ${prize.name}: ${prizeCountStr} tickets`); for (let i = 0; i < count; i += BATCH_SIZE) { const batch = Math.min(BATCH_SIZE, count - i); const values = []; for (let j = 0; j < batch; j++) { const code = generateCode(); values.push(`('${code}', '${prize.id}', NULL)`); } const query = `INSERT INTO tickets (code, prize_id, status) VALUES ${values.join(', ')}`; await pool.query(query); generated += batch; const genStr = generated.toLocaleString('fr-FR'); const totalStr = TOTAL_TICKETS.toLocaleString('fr-FR'); process.stdout.write(`\r Progression: ${genStr} / ${totalStr}`); } console.log(''); } const duration = ((Date.now() - start) / 1000).toFixed(2); const genStr = generated.toLocaleString('fr-FR'); console.log(`\n✅ Terminé! ${genStr} tickets générés en ${duration}s\n`); process.exit(0); } catch (error) { console.error('❌ Erreur:', error.message); console.error(error.stack); process.exit(1); } }; generateTickets();