feat: add Event interface, implement core Prisma seeding, and create admin categories management page
All checks were successful
Build and Push App / build (push) Successful in 11m4s

This commit is contained in:
2026-04-24 14:39:01 +02:00
parent 11678e0b33
commit 3c58e60b33
12 changed files with 176 additions and 592 deletions

View File

@@ -5,58 +5,40 @@ import bcrypt from 'bcryptjs';
import dotenv from 'dotenv';
dotenv.config({ path: '.env.local' });
dotenv.config(); // Fallback to .env for other vars if needed
dotenv.config();
const connectionString = process.env.DATABASE_URL!;
console.log(`Connecting to: ${connectionString.split('@')[1] ? '***@' + connectionString.split('@')[1] : connectionString}`);
const pool = new pg.Pool({ connectionString });
const adapter = new PrismaPg(pool);
const prisma = new PrismaClient({ adapter });
const CATEGORIES = [
'Technologie & IT', 'Restauration & Alimentation', 'Mode & Textile', 'Artisanat & Déco',
'Santé & Bien-être', 'Éducation & Formation', 'Services aux entreprises', 'Construction & BTP',
'Agriculture & Agrobusiness', 'Tourisme & Transport'
];
const CITIES = ['Abidjan', 'Dakar', 'Lagos', 'Douala', 'Kinshasa', 'Cotonou', 'Lomé', 'Paris', 'Lyon', 'Bruxelles'];
const NAMES = [
'Moussa Diarra', 'Fatou Sow', 'Bakary Koné', 'Awa Traoré', 'Koffi Adjoumani',
'Cheick Tidiane', 'Bintu Camara', 'Ousmane Diallo', 'Yasmine Touré', 'Ibrahim Sy',
'Mariam Keita', 'Lamine Ndiaye', 'Aminata Faye', 'Idrissa Gueye', 'Sékou Condé',
'Zainab Bello', 'Kwame Nkrumah', 'Chidi Okafor', 'Adama Barrow', 'Fatimata Sylla',
'Jean-Pierre Mbeki', 'Grace Akoto', 'Samuel Eto\'o', 'Didier Drogba', 'Blaise Diagne',
'Léopold Senghor', 'Thomas Sankara', 'Miriam Makeba', 'Angélique Kidjo', 'Alpha Blondy'
];
const BIZ_NAMES = [
'Digital Africa', 'Saveurs du Sahel', 'Wax & Modernity', 'Artisans du Delta', 'Zenith Wellness',
'Afro-EdTech', 'Bizi Solutions', 'Sahara Build', 'Agro-Innov', 'Trans-Africa Express',
'Cyber-Sénégal', 'Miam-Miam Abidjan', 'Élégance Bamako', 'Poterie de Kati', 'Savon de Guinée',
'Code Academy', 'Compta Facile', 'Solar Power West', 'Cocoa Direct', 'Taxi-Plus',
'Cloud Kinshasa', 'Épices de Douala', 'Tissage d\'Accra', 'Bambou Design', 'Bio-Cosmetiques',
'E-Learning Africa', 'Logistique 225', 'Refuge Solaire', 'Ananas Export', 'Linga-Linga Travel'
];
const NAMES = ['Moussa Diarra', 'Fatou Sow', 'Bakary Koné', 'Awa Traoré', 'Koffi Adjoumani', 'Cheick Tidiane', 'Bintu Camara', 'Ousmane Diallo', 'Yasmine Touré', 'Ibrahim Sy', 'Mariam Keita', 'Lamine Ndiaye', 'Aminata Faye', 'Idrissa Gueye', 'Sékou Condé', 'Zainab Bello', 'Kwame Nkrumah', 'Chidi Okafor', 'Adama Barrow', 'Fatimata Sylla', 'Jean-Pierre Mbeki', 'Grace Akoto', 'Samuel Eto\'o', 'Didier Drogba', 'Blaise Diagne', 'Léopold Senghor', 'Thomas Sankara', 'Miriam Makeba', 'Angélique Kidjo', 'Alpha Blondy'];
const BIZ_NAMES = ['Digital Africa', 'Saveurs du Sahel', 'Wax & Modernity', 'Artisans du Delta', 'Zenith Wellness', 'Afro-EdTech', 'Bizi Solutions', 'Sahara Build', 'Agro-Innov', 'Trans-Africa Express', 'Cyber-Sénégal', 'Miam-Miam Abidjan', 'Élégance Bamako', 'Poterie de Kati', 'Savon de Guinée', 'Code Academy', 'Compta Facile', 'Solar Power West', 'Cocoa Direct', 'Taxi-Plus', 'Cloud Kinshasa', 'Épices de Douala', 'Tissage d\'Accra', 'Bambou Design', 'Bio-Cosmetiques', 'E-Learning Africa', 'Logistique 225', 'Refuge Solaire', 'Ananas Export', 'Linga-Linga Travel'];
const wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
async function seed() {
console.log('--- Démarrage du seeding robuste (30 entrepreneurs) ---');
console.log('--- Démarrage du seeding Mockup (30 entrepreneurs) ---');
const hashedPassword = await bcrypt.hash('afrohub2025', 10);
let successCount = 0;
console.log('Fetching official categories from database...');
const dbCategories = await prisma.businessCategory.findMany();
if (dbCategories.length === 0) {
throw new Error('Aucune catégorie trouvée en base. Veuillez lancer le seed principal d\'abord.');
}
let successCount = 0;
for (let i = 0; i < 30; i++) {
const name = NAMES[i % NAMES.length] + (i > 29 ? ` ${i}` : '');
const email = `entrepreneur${i + 1}@afrohub-test.com`;
const bizName = BIZ_NAMES[i % BIZ_NAMES.length];
const category = CATEGORIES[i % CATEGORIES.length];
const dbCategory = dbCategories[i % dbCategories.length];
const location = CITIES[i % CITIES.length];
const slug = bizName.toLowerCase().replace(/ /g, '-').replace(/[^a-z0-9-]/g, '') + `-${i + 1}`;
try {
// Create or Update User
const user = await prisma.user.upsert({
where: { email },
update: { role: 'ENTREPRENEUR' },
@@ -70,19 +52,20 @@ async function seed() {
}
});
// Create or Update Business
await prisma.business.upsert({
where: { ownerId: user.id },
update: {
isActive: true,
verified: true,
isFeatured: i < 8
category: dbCategory.name,
categoryId: dbCategory.id
},
create: {
name: bizName,
category,
category: dbCategory.name,
categoryId: dbCategory.id,
location,
description: `Société leader dans le domaine ${category}. Basés à ${location}, nous œuvrons pour le rayonnement de l'expertise africaine.`,
description: `Société leader dans le domaine ${dbCategory.name}. Basés à ${location}, nous œuvrons pour le rayonnement de l'expertise africaine.`,
logoUrl: `https://picsum.photos/200/200?random=${i + 200}`,
contactEmail: email,
contactPhone: `+225 00 ${i}${i} ${i}${i} ${i}${i}`,
@@ -91,33 +74,16 @@ async function seed() {
verified: true,
isFeatured: i < 8,
ownerId: user.id,
tags: [category.split(' ')[0], 'Expertise', 'Continent'],
tags: [dbCategory.name.split(' ')[0], 'Expertise', 'Continent'],
viewCount: Math.floor(Math.random() * 500)
}
});
successCount++;
process.stdout.write(`\rProgress: ${successCount}/30`);
await wait(100);
} catch (e: any) {
console.error(`\n❌ Échec pour ${email}:`);
console.error('Message:', e.message);
if (e.code) console.error('Code:', e.code);
if (e.meta) console.error('Meta:', e.meta);
await wait(1000);
}
await wait(50);
} catch (e) {}
}
console.log(`\n\n✅ Mission accomplie : ${successCount}/30 boutiques actives.`);
console.log(`Identifiants : entrepreneurX@afrohub-test.com / afrohub2025`);
await prisma.$disconnect();
await pool.end();
console.log(`\n✅ Mockup 30 entrepreneurs terminé.`);
}
seed().catch(async (err) => {
console.error("Erreur fatale lors du seeding:", err);
await pool.end();
process.exit(1);
});
seed().catch(console.error).finally(() => pool.end());