edtech / apps /api /src /scripts /generate_bank_docs.ts
CognxSafeTrack
feat(ai): add bank-level pitch deck and business plan generator script
4d733e8
import PptxGenJS from 'pptxgenjs';
import puppeteer from 'puppeteer';
import * as path from 'path';
import * as fs from 'fs';
// Asset Paths
const assetsDir = '/Users/macbookair/.gemini/antigravity/brain/ea618d02-1ee0-47c1-a2b7-aed00a3604bc';
const outputDir = '/Volumes/sms/edtech/docs';
async function generateBankLevelPptx() {
console.log("Generating Premium PPTX...");
const pres = new PptxGenJS();
// Design System
pres.defineSlideMaster({
title: 'MASTER_SLIDE',
bkgd: 'FFFFFF',
objects: [
{ rect: { x: 0, y: 0, w: '100%', h: 0.75, fill: { color: '1B3A57' } } },
{ rect: { x: 0, y: 0.75, w: '100%', h: 0.05, fill: { color: 'F4A261' } } } // Orange accent
]
});
// 1. Cover Slide
const slide1 = pres.addSlide();
slide1.bkgd = '1B3A57';
slide1.addImage({ path: path.join(assetsDir, 'atelier_facade_1772852282648.png'), x: 0, y: 0, w: '100%', h: '100%' });
slide1.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: '100%', h: '100%', fill: { color: '000000', transparency: 60 } });
slide1.addText('SARTORIA NDOYE', { x: 0.5, y: 2, w: '90%', fontSize: 54, color: 'FFFFFF', bold: true, align: 'center', fontFace: 'Montserrat' });
slide1.addText('L\'Excellence Tradi-Moderne à Dakar - Business Plan 2026', { x: 0.5, y: 3.2, w: '90%', fontSize: 24, color: 'F4A261', align: 'center', fontFace: 'Inter' });
// 2. Problem/Solution
const slide2 = pres.addSlide({ masterName: 'MASTER_SLIDE' });
slide2.addText('1. MBIR MI AK SAFARA SI (Problème & Solution)', { x: 0.5, y: 0.15, w: '90%', fontSize: 28, color: 'FFFFFF', bold: true, fontFace: 'Montserrat' });
slide2.addText('Le Problème (Jafe-jafe bi):', { x: 0.5, y: 1.2, w: '40%', fontSize: 20, color: '1C7C54', bold: true });
slide2.addText('- Manque de tailleurs réguliers\n- Qualité des finitions aléatoire\n- Délais de livraison non respectés', { x: 0.5, y: 1.7, w: '40%', fontSize: 16, color: '333333', bullet: true });
slide2.addText('La Solution (Safara si):', { x: 5.5, y: 1.2, w: '40%', fontSize: 20, color: '1C7C54', bold: true });
slide2.addText('- Atelier premium standardisé\n- Promesse de tenues sur mesure à temps\n- Finitions parfaites (Contrôle Qualité)', { x: 5.5, y: 1.7, w: '40%', fontSize: 16, color: '333333', bullet: true });
slide2.addImage({ path: path.join(assetsDir, 'modern_workspace_1772852299569.png'), x: 0.5, y: 3.0, w: '40%', h: 2.2 });
slide2.addText('Notre Espace de Travail Moderne', { x: 0.5, y: 5.2, w: '40%', fontSize: 12, color: '666666', align: 'center' });
// 3. The Product
const slide3 = pres.addSlide({ masterName: 'MASTER_SLIDE' });
slide3.addText('2. LE PRODUIT : L\'EXCELLENCE (Qualité Supérieure)', { x: 0.5, y: 0.15, w: '90%', fontSize: 28, color: 'FFFFFF', bold: true, fontFace: 'Montserrat' });
slide3.addImage({ path: path.join(assetsDir, 'finishing_zoom_1772852316317.png'), x: 0.5, y: 1.2, w: 4, h: 4, rounding: true });
slide3.addText('Savoir-Faire Unique', { x: 5, y: 1.5, w: 4, fontSize: 24, color: '1B3A57', bold: true });
slide3.addText('Nous fusionnons le tissu traditionnel africain (Bazin, Wax) avec des textiles modernes.\n\nPoint critique : Les finitions.\nNotre atelier garantit des coutures nettes, des broderies précises et un tombé impeccable digne de la haute couture, à des prix accessibles.', { x: 5, y: 2.2, w: 4.5, fontSize: 18, color: '333333', lineSpacing: 28 });
// 4. Market
const slide4 = pres.addSlide({ masterName: 'MASTER_SLIDE' });
slide4.addText('3. MARCHE ET OPPORTUNITÉ (Marché à Dakar)', { x: 0.5, y: 0.15, w: '90%', fontSize: 28, color: 'FFFFFF', bold: true, fontFace: 'Montserrat' });
slide4.addText('Population de Dakar (2024)', { x: 0.5, y: 1.2, w: 3, fontSize: 16, color: '1C7C54', bold: true, align: 'center' });
slide4.addText('4,4 Millions', { x: 0.5, y: 1.6, w: 3, fontSize: 36, color: '1B3A57', bold: true, align: 'center' });
slide4.addText('Budget Mensuel Habillement', { x: 3.5, y: 1.2, w: 3, fontSize: 16, color: '1C7C54', bold: true, align: 'center' });
slide4.addText('12 000 FCFA', { x: 3.5, y: 1.6, w: 3, fontSize: 36, color: 'F4A261', bold: true, align: 'center' });
slide4.addText('Croissance Tradi-Moderne', { x: 6.5, y: 1.2, w: 3, fontSize: 16, color: '1C7C54', bold: true, align: 'center' });
slide4.addText('+15% / an', { x: 6.5, y: 1.6, w: 3, fontSize: 36, color: '1B3A57', bold: true, align: 'center' });
slide4.addText('TAM / SAM / SOM', { x: 0.5, y: 2.8, w: '90%', fontSize: 20, color: '1B3A57', bold: true });
slide4.addText('• TAM : Femmes de Dakar (Classe moyenne/Aisée) ~ 1.2 Millions\n• SAM : Femmes achetant des tenues pour évènements réguliers ~ 300 000\n• SOM : Cible pour notre atelier (Capacité année 1) ~ 1 500 clientes', { x: 0.5, y: 3.3, w: '90%', fontSize: 18, color: '333333', bullet: true, lineSpacing: 35 });
// 5. Financials
const slide5 = pres.addSlide({ masterName: 'MASTER_SLIDE' });
slide5.addText('4. PROJECTIONS FINANCIÈRES (Xaliss bi)', { x: 0.5, y: 0.15, w: '90%', fontSize: 28, color: 'FFFFFF', bold: true, fontFace: 'Montserrat' });
const chartData = [
{ name: 'Revenu', labels: ['Q1', 'Q2', 'Q3', 'Q4'], values: [3, 4.5, 7, 12] },
{ name: 'Coûts', labels: ['Q1', 'Q2', 'Q3', 'Q4'], values: [2.5, 3, 3.5, 4.5] }
];
slide5.addChart(pres.ChartType.bar, [chartData[0], chartData[1]], {
x: 0.5, y: 1.2, w: 6, h: 4,
chartColors: ['1C7C54', 'F4A261'],
showLegend: true, legendPos: 'b',
title: 'Prévisions Millions FCFA', showTitle: true,
valAxisTitle: 'Millions FCFA', catAxisTitle: 'Trimestres'
});
slide5.addText('Objectif de Rentabilité', { x: 6.8, y: 1.2, w: 3, fontSize: 20, color: '1B3A57', bold: true });
slide5.addText('Objectif mensuel J8 :\n300 000 FCFA net\n\nPrix moyen unitaire :\n15 000 FCFA\n\nMarge Brute estimée :\n60%', { x: 6.8, y: 1.7, w: 3, fontSize: 16, color: '333333' });
// 6. Team
const slide6 = pres.addSlide({ masterName: 'MASTER_SLIDE' });
slide6.addText('5. L\'ÉQUIPE DIRIGEANTE (Njiit yi)', { x: 0.5, y: 0.15, w: '90%', fontSize: 28, color: 'FFFFFF', bold: true, fontFace: 'Montserrat' });
slide6.addImage({ path: path.join(assetsDir, 'proud_entrepreneur_1772852329232.png'), x: 0.5, y: 1.2, w: 4, h: 4 });
slide6.addText('Fatou Ndoye\nFondatrice & Chef d\'Atelier', { x: 5, y: 1.5, w: 4.5, fontSize: 24, color: '1B3A57', bold: true });
slide6.addText('"Xam-xam bi ma jàng XAMLÉ dana ma dimbali ma gëna yokk sama business Couture. Sama yéne mooy defar ay ngënéel yu mag ci Sénégal."\n\n- 10 ans d\'expérience dans la mode locale.\n- Formation en gestion d\'entreprise XAMLÉ effectuée.', { x: 5, y: 2.5, w: 4.5, fontSize: 18, color: '333333', lineSpacing: 25 });
const pptxPath = path.join(outputDir, 'Sartoria_Ndoye_PitchDeck_Premium.pptx');
await pres.writeFile({ fileName: pptxPath });
console.log(`PPTX created at: ${pptxPath}`);
}
async function generateBankLevelPdf() {
console.log("Generating Premium PDF...");
const htmlContent = `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&family=Inter:wght@400;600&display=swap');
body { font-family: 'Inter', sans-serif; color: #333; margin: 0; padding: 40px; background-color: #fcfcfc; }
.container { max-width: 1000px; margin: auto; background: white; padding: 50px; box-shadow: 0 4px 15px rgba(0,0,0,0.05); }
header { display: flex; justify-content: space-between; align-items: center; border-bottom: 3px solid #1C7C54; padding-bottom: 20px; margin-bottom: 30px; }
h1 { font-family: 'Montserrat', sans-serif; color: #1B3A57; font-size: 38px; margin: 0; text-transform: uppercase; letter-spacing: 1px; }
.subtitle { color: #F4A261; font-weight: 600; font-size: 18px; margin-top: 5px; }
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; }
.section h2 { font-family: 'Montserrat', sans-serif; color: #1C7C54; font-size: 22px; border-bottom: 1px dashed #ccc; padding-bottom: 5px; text-transform: uppercase; }
.section p { font-size: 14px; line-height: 1.7; color: #555; }
.stats { display: flex; justify-content: space-between; background: #1B3A57; color: white; padding: 20px; border-radius: 8px; margin: 30px 0; }
.stat-box { text-align: center; }
.stat-number { font-size: 28px; font-weight: bold; font-family: 'Montserrat'; color: #F4A261; }
.stat-label { font-size: 12px; opacity: 0.9; text-transform: uppercase; }
.image-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-top: 20px; }
.image-grid img { width: 100%; height: 200px; object-fit: cover; border-radius: 8px; }
</style>
</head>
<body>
<div class="container">
<header>
<div>
<h1>Sartoria Ndoye</h1>
<div class="subtitle">L'Excellence Couture Tradi-Moderne (Dakar)</div>
</div>
<div>
<img src="file://${path.join(assetsDir, 'proud_entrepreneur_1772852329232.png')}" style="width:100px; height:100px; border-radius:50%; object-fit:cover; border: 3px solid #1C7C54;">
</div>
</header>
<div class="grid">
<div class="section">
<h2>Résumé Exécutif (Executive Summary)</h2>
<p>Fondée à Dakar, Sartoria Ndoye répond à un besoin crucial du marché de la mode sénégalaise : la fiabilité et la qualité des finitions. Nous ciblons une clientèle exigeante de femmes pour leurs tenues d'événements et professionnels, en fusionnant les pratiques traditionnelles avec des standards de conception modernes.</p>
</div>
<div class="section">
<h2>Marché & Opportunité (Market Size)</h2>
<p>Dakar représente un bassin de 4,4 millions d'habitants où la femme urbaine consacre en moyenne 12 000 FCFA par mois à l'habillement. Le segment "made in Sénégal" croît de 15% par an, porté par une fierté identitaire forte. Notre SOM (Serviceable Obtainable Market) initial est de 1 500 clientes récurrentes.</p>
</div>
</div>
<div class="stats">
<div class="stat-box"><div class="stat-number">15 000F</div><div class="stat-label">Prix Moyen Unitaire</div></div>
<div class="stat-box"><div class="stat-number">60%</div><div class="stat-label">Marge Brute Prévue</div></div>
<div class="stat-box"><div class="stat-number">300K F</div><div class="stat-label">Objectif Rentabilité Mensuelle</div></div>
<div class="stat-box"><div class="stat-number">B2C</div><div class="stat-label">Modèle d'Acquisition</div></div>
</div>
<div class="grid">
<div class="section">
<h2>Modèle Opérationnel & Stratégie (Go-to-Market)</h2>
<p>1. <b>Acquisition :</b> Campagnes sponsorisées Instagram (Focus sur la qualité visuelle des détails) et fidélisation relationnelle via WhatsApp Business.<br>
2. <b>Production :</b> Espace de travail standardisé et achat de machinerie haut de gamme (piqueuses plates, surjeteuses professionnelles). Collaboration avec les grossistes du marché HLM pour les matières premières.<br>
3. <b>Promesse :</b> "Des tenues sur mesure livrées à temps avec des finitions parfaites."</p>
</div>
<div class="section">
<h2>Focus sur la Qualité (Production)</h2>
<div class="image-grid">
<img src="file://${path.join(assetsDir, 'modern_workspace_1772852299569.png')}">
<img src="file://${path.join(assetsDir, 'finishing_zoom_1772852316317.png')}">
</div>
</div>
</div>
<div style="text-align: center; margin-top: 40px; font-size: 14px; color: #888;">
<i>Business Plan généré par la plateforme Moteur IA XAMLÉ</i>
</div>
</div>
</body>
</html>
`;
const browser = await puppeteer.launch({
executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || undefined,
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox', '--allow-file-access-from-files']
});
const page = await browser.newPage();
await page.setContent(htmlContent, { waitUntil: 'networkidle0' });
const pdfPath = path.join(outputDir, 'Sartoria_Ndoye_BusinessPlan_Premium.pdf');
await page.pdf({
path: pdfPath,
format: 'A4',
printBackground: true,
margin: { top: 0, bottom: 0, left: 0, right: 0 }
});
await browser.close();
console.log(`PDF created at: ${pdfPath}`);
}
async function run() {
console.log("Starting Bank-Level Generation...");
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
await generateBankLevelPptx();
await generateBankLevelPdf();
console.log("Documents successfully completed in docs/");
}
run().catch(console.error);