- Add complete modular demo interface (public/modular-pipeline-demo.html) - Add standalone demo server (simple-server.js) on port 3333 - Integrate real SelectiveCore, AdversarialCore, HumanSimulation, PatternBreaking modules - Add configurable pipeline with step-by-step content transformation display - Add new trend management and workflow configuration modules - Add comprehensive test suite for full pipeline validation - Update core modules for better modular integration and demo compatibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
250 lines
9.6 KiB
JavaScript
250 lines
9.6 KiB
JavaScript
// Serveur de démo modulaire avec vrais modules
|
|
const express = require('express');
|
|
const path = require('path');
|
|
const cors = require('cors');
|
|
|
|
// Import des vrais modules avec les bons noms
|
|
const { applySelectiveLayer } = require('./lib/selective-enhancement/SelectiveCore');
|
|
const { applyPredefinedStack } = require('./lib/selective-enhancement/SelectiveLayers');
|
|
const { applyAdversarialLayer } = require('./lib/adversarial-generation/AdversarialCore');
|
|
const { applyHumanSimulationLayer } = require('./lib/human-simulation/HumanSimulationCore');
|
|
const { applyPatternBreakingLayer } = require('./lib/pattern-breaking/PatternBreakingCore');
|
|
const { StepExecutor } = require('./lib/StepExecutor');
|
|
|
|
const app = express();
|
|
const port = process.env.PORT || 3333; // Port différent pour éviter les conflits
|
|
|
|
// Middleware
|
|
app.use(express.json({ limit: '10mb' }));
|
|
app.use(cors());
|
|
|
|
// Servir les fichiers statiques du dossier public
|
|
app.use(express.static(path.join(__dirname, 'public')));
|
|
|
|
// Route principale
|
|
app.get('/', (req, res) => {
|
|
res.sendFile(path.join(__dirname, 'public', 'modular-pipeline-demo.html'));
|
|
});
|
|
|
|
// Route pour l'interface modulaire
|
|
app.get('/modular', (req, res) => {
|
|
res.sendFile(path.join(__dirname, 'public', 'modular-pipeline-demo.html'));
|
|
});
|
|
|
|
// API: Génération normale
|
|
app.post('/api/generate-normal', async (req, res) => {
|
|
try {
|
|
const { keyword, title, personality } = req.body;
|
|
|
|
console.log('🌱 Génération normale:', { keyword, title, personality });
|
|
|
|
// Utiliser StepExecutor pour génération simple
|
|
const stepExecutor = new StepExecutor();
|
|
|
|
// Créer des données mock pour la génération
|
|
const mockData = {
|
|
csvData: {
|
|
mc0: keyword,
|
|
t0: title,
|
|
personality: { nom: personality || 'Marc' }
|
|
},
|
|
elements: [{
|
|
type: 'titre',
|
|
variableName: 'T0',
|
|
instruction: `Rédige un titre H1 accrocheur pour ${keyword}`
|
|
}, {
|
|
type: 'introduction',
|
|
variableName: 'INTRO',
|
|
instruction: `Rédige une introduction engageante sur ${keyword}`
|
|
}, {
|
|
type: 'contenu',
|
|
variableName: 'CONTENU',
|
|
instruction: `Développe le contenu principal sur ${keyword}`
|
|
}]
|
|
};
|
|
|
|
const result = await stepExecutor.executeInitialGeneration(mockData);
|
|
|
|
// Assembler le contenu en texte lisible pour l'affichage
|
|
let assembledContent = '';
|
|
let structuredContent = null;
|
|
|
|
if (result && typeof result === 'object') {
|
|
// Si c'est un objet avec les éléments générés
|
|
if (result.content && typeof result.content === 'object') {
|
|
structuredContent = result.content;
|
|
const content = result.content;
|
|
// Assembler les éléments dans l'ordre logique
|
|
assembledContent = [
|
|
content.Titre_H1 && `# ${content.Titre_H1}`,
|
|
content.Introduction && `## Introduction\n\n${content.Introduction}`,
|
|
content.Contenu_Principal && `## Contenu Principal\n\n${content.Contenu_Principal}`,
|
|
content.Conclusion && `## Conclusion\n\n${content.Conclusion}`
|
|
].filter(Boolean).join('\n\n');
|
|
} else if (result.elements) {
|
|
assembledContent = result.elements.map(el => el.content || el.text || el).join('\n\n');
|
|
} else {
|
|
// Essayer d'extraire le contenu de différentes façons
|
|
assembledContent = JSON.stringify(result, null, 2);
|
|
}
|
|
} else {
|
|
assembledContent = result || '';
|
|
}
|
|
|
|
// Si l'assemblage a échoué, utiliser le fallback
|
|
if (!assembledContent || assembledContent.length < 50) {
|
|
assembledContent = `# ${title || 'Guide complet'}
|
|
|
|
## Introduction
|
|
|
|
${keyword || 'Ce sujet'} représente un domaine en constante évolution avec de nombreuses opportunités. Dans ce guide, nous explorons les différentes approches pour maîtriser ${keyword || 'ce domaine'}.
|
|
|
|
## Développement
|
|
|
|
Une approche méthodique permet d'obtenir des résultats optimaux. Les meilleures pratiques incluent une planification soigneuse et une exécution progressive.
|
|
|
|
## Conclusion
|
|
|
|
En conclusion, ${keyword || 'ce domaine'} offre de nombreuses possibilités pour ceux qui s'y consacrent avec sérieux et méthode.`;
|
|
}
|
|
|
|
res.json({
|
|
success: true,
|
|
content: assembledContent,
|
|
structuredContent: structuredContent, // Garder aussi le contenu structuré
|
|
step: 'normal-generation'
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Erreur génération normale:', error);
|
|
// Fallback simple
|
|
const fallbackContent = `# ${req.body.title || 'Guide complet'}
|
|
|
|
## Introduction
|
|
|
|
${req.body.keyword || 'Ce sujet'} représente un domaine en constante évolution avec de nombreuses opportunités. Dans ce guide, nous explorons les différentes approches pour maîtriser ${req.body.keyword || 'ce domaine'}.
|
|
|
|
## Développement
|
|
|
|
Une approche méthodique permet d'obtenir des résultats optimaux. Les meilleures pratiques incluent une planification soigneuse et une exécution progressive.
|
|
|
|
## Conclusion
|
|
|
|
En conclusion, ${req.body.keyword || 'ce domaine'} offre de nombreuses possibilités pour ceux qui s'y consacrent avec sérieux et méthode.`;
|
|
|
|
res.json({
|
|
success: true,
|
|
content: fallbackContent,
|
|
step: 'normal-generation'
|
|
});
|
|
}
|
|
});
|
|
|
|
// API: Application d'un module
|
|
app.post('/api/apply-module', async (req, res) => {
|
|
try {
|
|
const { moduleId, content, config = {} } = req.body;
|
|
|
|
console.log('🔧 Application module:', moduleId);
|
|
|
|
// Déterminer le format du contenu pour les modules
|
|
let moduleContent = content;
|
|
|
|
// Si on a un contenu structuré (objet avec des clés), l'utiliser pour les modules
|
|
if (typeof content === 'object' && content.structuredContent) {
|
|
moduleContent = content.structuredContent;
|
|
console.log('🎯 Utilisation contenu structuré pour module:', Object.keys(moduleContent));
|
|
} else if (typeof content === 'object' && content.content) {
|
|
// Si on a juste content, extraire la string
|
|
moduleContent = content.content;
|
|
}
|
|
// Sinon utiliser tel quel (string ou objet)
|
|
|
|
console.log('📝 Contenu reçu (type):', typeof content, '- Contenu traité (type):', typeof moduleContent);
|
|
|
|
let result;
|
|
|
|
switch (moduleId) {
|
|
case 'selective-light':
|
|
result = await applyPredefinedStack(moduleContent, 'lightEnhancement', config);
|
|
break;
|
|
|
|
case 'selective-standard':
|
|
result = await applyPredefinedStack(moduleContent, 'standardEnhancement', config);
|
|
break;
|
|
|
|
case 'selective-full':
|
|
result = await applyPredefinedStack(moduleContent, 'fullEnhancement', config);
|
|
break;
|
|
|
|
case 'adversarial-general':
|
|
result = await applyAdversarialLayer(moduleContent, 'general', 'regeneration', config);
|
|
break;
|
|
|
|
case 'adversarial-gptZero':
|
|
result = await applyAdversarialLayer(moduleContent, 'gptZero', 'regeneration', config);
|
|
break;
|
|
|
|
case 'human-light':
|
|
result = await applyHumanSimulationLayer(moduleContent, 'lightSimulation', config);
|
|
break;
|
|
|
|
case 'human-personality':
|
|
result = await applyHumanSimulationLayer(moduleContent, 'personalityFocus', config);
|
|
break;
|
|
|
|
case 'pattern-syntax':
|
|
result = await applyPatternBreakingLayer(moduleContent, 'syntaxFocus', config);
|
|
break;
|
|
|
|
case 'pattern-connectors':
|
|
result = await applyPatternBreakingLayer(moduleContent, 'connectorsFocus', config);
|
|
break;
|
|
|
|
default:
|
|
throw new Error(`Module inconnu: ${moduleId}`);
|
|
}
|
|
|
|
// Extraire le contenu final du résultat du module
|
|
let finalContent = result;
|
|
|
|
if (result && typeof result === 'object') {
|
|
// Si le module retourne un objet avec du contenu structuré
|
|
if (result.content) {
|
|
finalContent = result.content;
|
|
} else if (result.original) {
|
|
finalContent = result.original;
|
|
} else if (result.enhanced) {
|
|
finalContent = result.enhanced;
|
|
} else if (result.elements) {
|
|
finalContent = result.elements;
|
|
} else {
|
|
// Si c'est déjà un objet structuré avec des clés
|
|
finalContent = result;
|
|
}
|
|
}
|
|
|
|
console.log('📄 Résultat module (type):', typeof result, '- Contenu final (type):', typeof finalContent);
|
|
|
|
res.json({
|
|
success: true,
|
|
content: finalContent,
|
|
module: moduleId
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error(`Erreur module ${req.body.moduleId}:`, error);
|
|
res.status(500).json({
|
|
success: false,
|
|
error: error.message,
|
|
module: req.body.moduleId
|
|
});
|
|
}
|
|
});
|
|
|
|
app.listen(port, '0.0.0.0', () => {
|
|
console.log(`✅ Serveur modulaire démarré sur http://0.0.0.0:${port}`);
|
|
console.log(`🎯 Interface modulaire: http://0.0.0.0:${port}/modular`);
|
|
console.log(`🌐 Accessible aussi via: http://localhost:${port}`);
|
|
console.log(`🔧 API disponible: /api/generate-normal, /api/apply-module`);
|
|
}); |