feat: implement core platform features including business directory, admin dashboard, authentication, and API infrastructure
Some checks failed
Build and Push App / build (push) Failing after 16m2s

This commit is contained in:
2026-04-18 22:10:19 +02:00
parent 6ec1a3ae84
commit 3e2063e4fa
89 changed files with 4405 additions and 967 deletions

23
scratch/check_db.ts Normal file
View File

@@ -0,0 +1,23 @@
import { PrismaClient } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg';
import pg from 'pg';
import dotenv from 'dotenv';
dotenv.config({ path: '.env.local' });
const connectionString = process.env.DATABASE_URL!;
const pool = new pg.Pool({ connectionString });
const adapter = new PrismaPg(pool);
const prisma = new PrismaClient({ adapter });
async function check() {
const featured = await prisma.business.findMany({
where: { isFeatured: true },
});
console.log('--- ALL Featured Businesses in DB ---');
console.log(JSON.stringify(featured, null, 2));
await prisma.$disconnect();
await pool.end();
}
check();

53
scratch/fix_db.ts Normal file
View File

@@ -0,0 +1,53 @@
import { PrismaClient } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg';
import pg from 'pg';
import dotenv from 'dotenv';
dotenv.config({ path: '.env.local' });
const connectionString = process.env.DATABASE_URL!;
const pool = new pg.Pool({ connectionString });
const adapter = new PrismaPg(pool);
const prisma = new PrismaClient({ adapter });
async function fix() {
console.log('--- Nettoyage et stabilisation des données vedettes ---');
// 1. Désactiver 'isFeatured' pour tout le monde par défaut
await prisma.business.updateMany({
data: { isFeatured: false }
});
// 2. Activer isFeatured pour les 8 premiers (comme prévu dans le seed)
// On va chercher les 8 premières entreprises créées
const firstEight = await prisma.business.findMany({
take: 8,
orderBy: { createdAt: 'asc' }
});
for (const biz of firstEight) {
await prisma.business.update({
where: { id: biz.id },
data: {
isFeatured: true,
// On s'assure que le keyMetric est propre
keyMetric: biz.keyMetric === 'susu land' ? '+50 Projets Livrés' : biz.keyMetric
}
});
}
// 3. Fix spécifique pour Ananas Export s'il n'est pas dans les 8
await prisma.business.updateMany({
where: { name: 'Ananas Export' },
data: {
keyMetric: 'Leader Export Fruits',
isFeatured: true // On le garde en vedette car l'utilisateur l'aime bien apparemment
}
});
console.log('✅ Données stabilisées.');
await prisma.$disconnect();
await pool.end();
}
fix();

66
scratch/seed_legal.ts Normal file
View File

@@ -0,0 +1,66 @@
import { PrismaClient } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg';
import pg from 'pg';
import dotenv from 'dotenv';
dotenv.config({ path: '.env.local' });
dotenv.config({ path: '.env' });
const connectionString = process.env.DATABASE_URL!;
const pool = new pg.Pool({ connectionString });
const adapter = new PrismaPg(pool);
const prisma = new PrismaClient({ adapter });
async function main() {
console.log('🌱 Seeding initial legal documents...');
const cguContent = `
<h2>1. Présentation du site</h2>
<p>En vertu de l'article 6 de la loi n° 2004-575 du 21 juin 2004 pour la confiance dans l'économie numérique...</p>
<h2>2. Conditions générales dutilisation du site et des services proposés</h2>
<p>Lutilisation du site Afrohub implique lacceptation pleine et entière des conditions générales dutilisation ci-après décrites.</p>
<h2>3. Description des services fournis</h2>
<p>Le site Afrohub a pour objet de fournir une plateforme de mise en relation entre entrepreneurs africains et clients.</p>
<h2>4. Limitations contractuelles sur les données techniques</h2>
<p>Le site utilise la technologie JavaScript (Next.js).</p>
<h2>5. Propriété intellectuelle et contrefaçons</h2>
<p>Afrohub est propriétaire des droits de propriété intellectuelle sur tous les éléments accessibles sur le site.</p>
`;
const cgvContent = `
<h2>1. Objet</h2>
<p>Les présentes conditions générales de vente (CGV) régissent les relations contractuelles entre la plateforme Afrohub et les inscrits.</p>
<h2>2. Description des services payants</h2>
<p>Afrohub propose divers services payants destinés aux entrepreneurs (Pack Booster, Empire).</p>
<h2>3. Tarifs et paiement</h2>
<p>Les prix de nos services sont indiqués en euros (ou monnaie locale) toutes taxes comprises.</p>
<h2>4. Droit de rétractation</h2>
<p>Conformément à la loi, le droit de rétractation ne s'applique pas aux services numériques immédiatement exécutés.</p>
`;
await prisma.legalDocument.upsert({
where: { type: 'CGU' },
update: {},
create: {
type: 'CGU',
title: "Conditions Générales d'Utilisation",
content: cguContent
}
});
await prisma.legalDocument.upsert({
where: { type: 'CGV' },
update: {},
create: {
type: 'CGV',
title: "Conditions Générales de Vente",
content: cgvContent
}
});
console.log('✅ Legal documents seeded!');
}
main()
.catch(console.error)
.finally(() => prisma.$disconnect());

71
scratch/seed_stats.ts Normal file
View File

@@ -0,0 +1,71 @@
import { PrismaClient } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg';
import pg from 'pg';
import dotenv from 'dotenv';
dotenv.config({ path: '.env.local' });
const connectionString = process.env.DATABASE_URL!;
const pool = new pg.Pool({ connectionString });
const adapter = new PrismaPg(pool);
const prisma = new PrismaClient({ adapter });
async function main() {
const business = await prisma.business.findFirst();
if (!business) {
console.log("No business found to seed stats for.");
return;
}
console.log(`Seeding stats for business: ${business.name} (${business.id})`);
const events = [];
const typeViews = 'BUSINESS_VIEW';
const typeClicks = 'BUSINESS_CONTACT_CLICK';
// Seed last 30 days
for (let i = 0; i < 30; i++) {
const date = new Date();
date.setDate(date.getDate() - i);
// Random number of views (5 to 50)
const viewCount = Math.floor(Math.random() * 45) + 5;
for (let j = 0; j < viewCount; j++) {
events.push({
type: typeViews,
path: `/annuaire/${business.id}`,
label: business.name,
metadata: { businessId: business.id },
createdAt: new Date(date.getTime() + Math.random() * 3600000 * 24) // Random time in that day
});
}
// Random number of clicks (0 to 10)
const clickCount = Math.floor(Math.random() * 11);
for (let k = 0; k < clickCount; k++) {
events.push({
type: typeClicks,
path: `/annuaire/${business.id}`,
label: business.name,
metadata: { businessId: business.id },
createdAt: new Date(date.getTime() + Math.random() * 3600000 * 24)
});
}
}
// Batch insert
await prisma.analyticsEvent.createMany({
data: events
});
console.log(`Successfully seeded ${events.length} events.`);
}
main()
.catch(e => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});

22
scratch/test-geoip.ts Normal file
View File

@@ -0,0 +1,22 @@
// Run with npx ts-node scratch/test-geoip.ts
import { getGeoInfo } from '../lib/geo';
async function test() {
const testIps = [
'8.8.8.8', // Google (US)
'41.207.160.0', // Orange (CI)
'1.1.1.1', // Cloudflare (AU/US)
'102.64.170.0', // Maroc Telecom (MA)
'127.0.0.1' // Local
];
console.log('Testing GeoIP Detection...\n');
for (const ip of testIps) {
const mockHeaders = new Headers();
const result = await getGeoInfo(ip, mockHeaders);
console.log(`IP: ${ip.padEnd(15)} => Country: ${result.country.padEnd(20)} City: ${result.city}`);
}
}
test();

View File

@@ -0,0 +1,44 @@
import { PrismaClient } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg';
import pg from 'pg';
async function main() {
const connectionString = process.env.DATABASE_URL;
if (!connectionString) {
console.error('DATABASE_URL is not set');
process.exit(1);
}
const pool = new pg.Pool({ connectionString });
const adapter = new PrismaPg(pool);
const prisma = new PrismaClient({ adapter });
console.log('🔄 Updating Site Settings in database...');
try {
const settings = await prisma.siteSetting.upsert({
where: { id: 'singleton' },
update: {
siteName: 'Afrohub',
siteSlogan: "La plateforme de référence pour l'entrepreneuriat africain. Visibilité, connexion et croissance pour les TPE/PME.",
contactEmail: 'support@afrohub.com',
footerText: '© 2025 Afrohub. Tous droits réservés.',
},
create: {
id: 'singleton',
siteName: 'Afrohub',
siteSlogan: "La plateforme de référence pour l'entrepreneuriat africain. Visibilité, connexion et croissance pour les TPE/PME.",
contactEmail: 'support@afrohub.com',
footerText: '© 2025 Afrohub. Tous droits réservés.',
},
});
console.log('✅ Settings updated:', settings);
} catch (error) {
console.error('❌ Error updating settings:', error);
} finally {
await prisma.$disconnect();
}
}
main();