seo-generator-server/simple-server.js
StillHammer f51c4095f6 Add modular pipeline demo system with real module integration
- 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>
2025-09-23 16:03:20 +08:00

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`);
});