seo-generator-server/lib/human-simulation/HumanSimulationTracker.js
StillHammer 9a2ef7da2b feat(human-simulation): Système d'erreurs graduées procédurales + anti-répétition complet
## 🎯 Nouveau système d'erreurs graduées (architecture SmartTouch)

### Architecture procédurale intelligente :
- **3 niveaux de gravité** : Légère (50%) → Moyenne (30%) → Grave (10%)
- **14 types d'erreurs** réalistes et subtiles
- **Sélection procédurale** selon contexte (longueur, technique, heure)
- **Distribution contrôlée** : max 1 grave, 2 moyennes, 3 légères par article

### 1. Erreurs GRAVES (10% articles max) :
- Accord sujet-verbe : "ils sont" → "ils est"
- Mot manquant : "pour garantir la qualité" → "pour garantir qualité"
- Double mot : "pour garantir" → "pour pour garantir"
- Négation oubliée : "n'est pas" → "est pas"

### 2. Erreurs MOYENNES (30% articles) :
- Accord pluriel : "plaques résistantes" → "plaques résistant"
- Virgule manquante : "Ainsi, il" → "Ainsi il"
- Registre inapproprié : "Par conséquent" → "Du coup"
- Préposition incorrecte : "résistant aux" → "résistant des"
- Connecteur illogique : "cependant" → "donc"

### 3. Erreurs LÉGÈRES (50% articles) :
- Double espace : "de votre" → "de  votre"
- Trait d'union : "c'est-à-dire" → "c'est à dire"
- Espace ponctuation : "qualité ?" → "qualité?"
- Majuscule : "Toutenplaque" → "toutenplaque"
- Apostrophe droite : "l'article" → "l'article"

##  Système anti-répétition complet :

### Corrections critiques :
- **HumanSimulationTracker.js** : Tracker centralisé global
- **Word boundaries (\b)** sur TOUS les regex → FIX "maison" → "néanmoinson"
- **Protection 30+ expressions idiomatiques** françaises
- **Anti-répétition** : max 2× même mot, jamais 2× même développement
- **Diversification** : 48 variantes (hésitations, développements, connecteurs)

### Nouvelle structure (comme SmartTouch) :
```
lib/human-simulation/
├── error-profiles/                (NOUVEAU)
│   ├── ErrorProfiles.js          (définitions + probabilités)
│   ├── ErrorGrave.js             (10% articles)
│   ├── ErrorMoyenne.js           (30% articles)
│   ├── ErrorLegere.js            (50% articles)
│   └── ErrorSelector.js          (sélection procédurale)
├── HumanSimulationCore.js         (orchestrateur)
├── HumanSimulationTracker.js      (anti-répétition)
└── [autres modules]
```

## 🔄 Remplace ancien système :
-  SpellingErrors.js (basique, répétitif, "et" → "." × 8)
-  error-profiles/ (gradué, procédural, intelligent, diversifié)

## 🎲 Fonctionnalités procédurales :
- Analyse contexte : longueur texte, complexité technique, heure rédaction
- Multiplicateurs adaptatifs selon contexte
- Conditions application intelligentes
- Tracking global par batch (respecte limites 10%/30%/50%)

## 📊 Résultats validation :
Sur 100 articles → ~40-50 avec erreurs subtiles et diverses (plus de spam répétitif)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 01:06:28 +08:00

182 lines
5.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ========================================
// FICHIER: HumanSimulationTracker.js
// RESPONSABILITÉ: Système anti-répétition centralisé
// Empêche spam de mots/phrases identiques
// ========================================
const { logSh } = require('../ErrorReporting');
/**
* CLASSE TRACKER CENTRALISÉ
* Partage entre tous les modules Human Simulation
*/
class HumanSimulationTracker {
constructor() {
// Mots injectés (répétitions personnalité, fatigue)
this.injectedWords = new Set();
// Développements de phrases utilisés (soir)
this.usedDevelopments = new Set();
// Hésitations utilisées (fatigue élevée)
this.usedHesitations = new Set();
// Compteur fautes orthographe/grammaire
this.spellingErrorsApplied = 0;
// Stats globales
this.stats = {
wordsInjected: 0,
developmentsAdded: 0,
hesitationsAdded: 0,
spellingErrorsAdded: 0,
blockedRepetitions: 0
};
logSh('🧠 HumanSimulationTracker initialisé', 'DEBUG');
}
/**
* VÉRIFIER SI UN MOT PEUT ÊTRE INJECTÉ
* @param {string} word - Mot à injecter
* @param {string} content - Contenu actuel
* @param {number} maxOccurrences - Maximum occurrences autorisées (défaut: 2)
* @returns {boolean} - true si injection autorisée
*/
canInjectWord(word, content, maxOccurrences = 2) {
// Compter occurrences actuelles dans le contenu
const regex = new RegExp(`\\b${word}\\b`, 'gi');
const currentCount = (content.match(regex) || []).length;
// Vérifier si déjà injecté précédemment
const alreadyInjected = this.injectedWords.has(word.toLowerCase());
// Autoriser si < maxOccurrences ET pas déjà injecté
const canInject = currentCount < maxOccurrences && !alreadyInjected;
if (!canInject) {
logSh(` 🚫 Injection bloquée: "${word}" (déjà ${currentCount}× présent ou déjà injecté)`, 'DEBUG');
this.stats.blockedRepetitions++;
}
return canInject;
}
/**
* ENREGISTRER MOT INJECTÉ
* @param {string} word - Mot qui a été injecté
*/
trackInjectedWord(word) {
this.injectedWords.add(word.toLowerCase());
this.stats.wordsInjected++;
logSh(` ✅ Mot tracké: "${word}" (total: ${this.stats.wordsInjected})`, 'DEBUG');
}
/**
* VÉRIFIER SI UN DÉVELOPPEMENT PEUT ÊTRE UTILISÉ
* @param {string} development - Développement à ajouter
* @returns {boolean} - true si autorisation
*/
canUseDevelopment(development) {
const canUse = !this.usedDevelopments.has(development);
if (!canUse) {
logSh(` 🚫 Développement bloqué: déjà utilisé dans ce texte`, 'DEBUG');
this.stats.blockedRepetitions++;
}
return canUse;
}
/**
* ENREGISTRER DÉVELOPPEMENT UTILISÉ
* @param {string} development - Développement ajouté
*/
trackDevelopment(development) {
this.usedDevelopments.add(development);
this.stats.developmentsAdded++;
logSh(` ✅ Développement tracké (total: ${this.stats.developmentsAdded})`, 'DEBUG');
}
/**
* VÉRIFIER SI HÉSITATION PEUT ÊTRE AJOUTÉE
* @param {string} hesitation - Hésitation à ajouter
* @returns {boolean} - true si autorisation
*/
canUseHesitation(hesitation) {
const canUse = !this.usedHesitations.has(hesitation);
if (!canUse) {
logSh(` 🚫 Hésitation bloquée: déjà utilisée`, 'DEBUG');
this.stats.blockedRepetitions++;
}
return canUse;
}
/**
* ENREGISTRER HÉSITATION UTILISÉE
* @param {string} hesitation - Hésitation ajoutée
*/
trackHesitation(hesitation) {
this.usedHesitations.add(hesitation);
this.stats.hesitationsAdded++;
logSh(` ✅ Hésitation trackée: "${hesitation}" (total: ${this.stats.hesitationsAdded})`, 'DEBUG');
}
/**
* VÉRIFIER SI FAUTE ORTHOGRAPHE PEUT ÊTRE APPLIQUÉE
* Maximum 1 faute par texte complet
* @returns {boolean} - true si autorisation
*/
canApplySpellingError() {
const canApply = this.spellingErrorsApplied === 0;
if (!canApply) {
logSh(` 🚫 Faute spelling bloquée: déjà ${this.spellingErrorsApplied} faute(s) dans ce texte`, 'DEBUG');
}
return canApply;
}
/**
* ENREGISTRER FAUTE ORTHOGRAPHE APPLIQUÉE
*/
trackSpellingError() {
this.spellingErrorsApplied++;
this.stats.spellingErrorsAdded++;
logSh(` ✅ Faute spelling trackée (total: ${this.stats.spellingErrorsAdded})`, 'DEBUG');
}
/**
* OBTENIR STATISTIQUES
* @returns {object} - Stats complètes
*/
getStats() {
return {
...this.stats,
injectedWords: Array.from(this.injectedWords),
usedDevelopments: this.usedDevelopments.size,
usedHesitations: this.usedHesitations.size,
spellingErrorsApplied: this.spellingErrorsApplied
};
}
/**
* RÉINITIALISER TRACKER (pour nouveau texte)
*/
reset() {
this.injectedWords.clear();
this.usedDevelopments.clear();
this.usedHesitations.clear();
this.spellingErrorsApplied = 0;
logSh('🔄 HumanSimulationTracker réinitialisé', 'DEBUG');
}
}
// ============= EXPORTS =============
module.exports = {
HumanSimulationTracker
};